diff options
author | Santiago Fernandez Madero <safern@microsoft.com> | 2019-04-04 21:47:31 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-04 21:47:31 -0700 |
commit | de68c9ddd18f863fd67098ab28d19206c9c66627 (patch) | |
tree | d2ec422cc8ace87b9497a7a599e827ea8fdff017 /src | |
parent | df804273f7bebbe45cb51f22b748c31b5fbe60cf (diff) | |
parent | bd050290780b1a51331fb8f78fd33d26ea1f21d3 (diff) | |
download | coreclr-de68c9ddd18f863fd67098ab28d19206c9c66627.tar.gz coreclr-de68c9ddd18f863fd67098ab28d19206c9c66627.tar.bz2 coreclr-de68c9ddd18f863fd67098ab28d19206c9c66627.zip |
Merge pull request #23633 from dotnet/NullableFeature
Nullable feature into master
Diffstat (limited to 'src')
450 files changed, 2969 insertions, 2599 deletions
diff --git a/src/System.Private.CoreLib/Resources/Strings.resx b/src/System.Private.CoreLib/Resources/Strings.resx index e4da94b055..9fed81d6bf 100644 --- a/src/System.Private.CoreLib/Resources/Strings.resx +++ b/src/System.Private.CoreLib/Resources/Strings.resx @@ -2935,9 +2935,6 @@ <data name="NotSupported_DBNullSerial" xml:space="preserve"> <value>Only one DBNull instance may exist, and calls to DBNull deserialization methods are not allowed.</value> </data> - <data name="NotSupported_DelegateSerHolderSerial" xml:space="preserve"> - <value>DelegateSerializationHolder objects are designed to represent a delegate during serialization and are not serializable themselves.</value> - </data> <data name="NotSupported_DynamicAssembly" xml:space="preserve"> <value>The invoked member is not supported in a dynamic assembly.</value> </data> diff --git a/src/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/System.Private.CoreLib.csproj index 93d24e4ef6..96b9584874 100644 --- a/src/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -25,7 +25,9 @@ <CLSCompliant>true</CLSCompliant> <WarningLevel>4</WarningLevel> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> - <NoWarn>649,1573,1591,0419,BCL0020</NoWarn> <!-- Remove BCL0020 once https://github.com/dotnet/arcade/pull/2158 is available --> + <!-- Remove BCL0020 once https://github.com/dotnet/arcade/pull/2158 is available + Remove CS8608 once https://github.com/dotnet/roslyn/issues/23268 is resolved --> + <NoWarn>649,1573,1591,0419,BCL0020,CS8609</NoWarn> <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute> <SignAssembly>true</SignAssembly> <DelaySign>true</DelaySign> diff --git a/src/System.Private.CoreLib/shared/Internal/Resources/PRIExceptionInfo.cs b/src/System.Private.CoreLib/shared/Internal/Resources/PRIExceptionInfo.cs index 6593c27b1a..1ae4674a98 100644 --- a/src/System.Private.CoreLib/shared/Internal/Resources/PRIExceptionInfo.cs +++ b/src/System.Private.CoreLib/shared/Internal/Resources/PRIExceptionInfo.cs @@ -2,13 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; - +#nullable enable namespace Internal.Resources { public class PRIExceptionInfo { - public string PackageSimpleName; - public string ResWFile; + public string? PackageSimpleName; + public string? ResWFile; } } diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Access.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Access.cs index a723f572a5..62b212b807 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Access.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Access.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ChDir.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ChDir.cs index 3c66995182..ebfa8738c9 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ChDir.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ChDir.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Close.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Close.cs index 8d192398a0..0c5ca55d8c 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Close.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Close.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FLock.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FLock.cs index 22934a3e77..b4b5902920 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FLock.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FLock.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FSync.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FSync.cs index e3ab970931..5660aecce5 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FSync.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FSync.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FTruncate.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FTruncate.cs index 5dad650362..6d6b368111 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FTruncate.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.FTruncate.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetCpuUtilization.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetCpuUtilization.cs index 35e77c4541..701c01cd9c 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetCpuUtilization.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetCpuUtilization.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetCwd.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetCwd.cs index a8bef6bde8..2951d441d2 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetCwd.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetCwd.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Buffers; using System.Runtime.InteropServices; @@ -14,12 +15,12 @@ internal static partial class Interop private static extern unsafe byte* GetCwd(byte* buffer, int bufferLength); internal static unsafe string GetCwd() - { + { const int StackLimit = 256; - + // First try to get the path into a buffer on the stack byte* stackBuf = stackalloc byte[StackLimit]; - string result = GetCwdHelper(stackBuf, StackLimit); + string? result = GetCwdHelper(stackBuf, StackLimit); if (result != null) { return result; @@ -50,7 +51,7 @@ internal static partial class Interop while (true); } - private static unsafe string GetCwdHelper(byte* ptr, int bufferSize) + private static unsafe string? GetCwdHelper(byte* ptr, int bufferSize) { // Call the real getcwd byte* result = GetCwd(ptr, bufferSize); diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetEUid.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetEUid.cs index 8b525fa327..98f5545f90 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetEUid.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetEUid.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetHostName.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetHostName.cs index 1ecade65ee..6d2fdc58cc 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetHostName.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetHostName.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetPid.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetPid.cs index 02d259db7d..2656753655 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetPid.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetPid.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetPwUid.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetPwUid.cs index 56d55c948f..cbab70a971 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetPwUid.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetPwUid.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; @@ -20,7 +21,7 @@ internal static partial class Interop internal byte* UserInfo; internal byte* HomeDirectory; internal byte* Shell; - }; + } [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetPwUidR", SetLastError = false)] internal static extern unsafe int GetPwUidR(uint uid, out Passwd pwd, byte* buf, int bufLen); diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetRandomBytes.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetRandomBytes.cs index e911b13583..7956567e8b 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetRandomBytes.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetRandomBytes.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetSystemTimeAsTicks.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetSystemTimeAsTicks.cs index f02ecac13b..35e37834e1 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetSystemTimeAsTicks.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetSystemTimeAsTicks.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; internal static partial class Interop diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetTimestamp.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetTimestamp.cs index b57c0cd175..d1669b6095 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetTimestamp.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetTimestamp.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; internal static partial class Interop diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetUnixName.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetUnixName.cs index 33664c4d39..6f3c3ff78d 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetUnixName.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetUnixName.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetUnixRelease.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetUnixRelease.cs index 5e41ae9804..5885de678f 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetUnixRelease.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetUnixRelease.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; internal static partial class Interop diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.LSeek.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.LSeek.cs index 7f8df7c6bf..3f93192422 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.LSeek.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.LSeek.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.LockFileRegion.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.LockFileRegion.cs index 23b48a4f5d..ecc95c4dc6 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.LockFileRegion.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.LockFileRegion.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; @@ -14,7 +15,7 @@ internal static partial class Interop F_WRLCK = 1, // exclusive or write lock F_UNLCK = 2 // unlock } - + [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_LockFileRegion", SetLastError=true)] internal static extern int LockFileRegion(SafeHandle fd, long offset, long length, LockType lockType); } diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.MksTemps.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.MksTemps.cs index b8694d9007..e9624591b3 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.MksTemps.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.MksTemps.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; @@ -11,7 +12,7 @@ internal static partial class Interop { [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_MksTemps", SetLastError = true)] internal static extern IntPtr MksTemps( - byte[] template, + byte[] template, int suffixlen); } } diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.MountPoints.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.MountPoints.cs index 7e31197149..913b7ebbb7 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.MountPoints.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.MountPoints.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Open.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Open.cs index a9a994c78c..e151c4cf75 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Open.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Open.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.OpenFlags.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.OpenFlags.cs index f9e54c3cbc..ce5f9ad70f 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.OpenFlags.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.OpenFlags.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; internal static partial class Interop diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.PathConf.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.PathConf.cs index 7213cb0264..27d5095a16 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.PathConf.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.PathConf.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Permissions.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Permissions.cs index f1d13787d2..5cddd425bc 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Permissions.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Permissions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; internal static partial class Interop diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.PosixFAdvise.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.PosixFAdvise.cs index ad8b73aed2..3035c5ecb4 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.PosixFAdvise.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.PosixFAdvise.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Read.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Read.cs index 233feabdbb..e835b7ff65 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Read.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Read.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ReadDir.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ReadDir.cs index cacb3664db..a55ca83204 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ReadDir.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ReadDir.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ReadLink.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ReadLink.cs index 50f1ae545e..f78fd1a806 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ReadLink.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.ReadLink.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; using System.Buffers; using System.Text; @@ -30,7 +31,7 @@ internal static partial class Interop /// <returns> /// Returns the link to the target path on success; and null otherwise. /// </returns> - public static string ReadLink(string path) + public static string? ReadLink(string path) { int bufferSize = 256; do diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Stat.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Stat.cs index d06fbda718..ff4699c782 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Stat.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Stat.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.SysConf.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.SysConf.cs index be0c0dee7b..1482b28614 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.SysConf.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.SysConf.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; internal static partial class Interop diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.SysLog.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.SysLog.cs index 6b6a74b743..85eef43383 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.SysLog.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.SysLog.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; internal static partial class Interop diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Unlink.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Unlink.cs index 829210fa7e..bbeb8896e8 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Unlink.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Unlink.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Write.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Write.cs index fb06d463be..761cd16353 100644 --- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Write.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Write.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs index b562e527e7..8ff166c958 100644 --- a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.EventWaitHandle.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Microsoft.Win32.SafeHandles; using System; using System.Runtime.InteropServices; @@ -20,7 +21,7 @@ internal static partial class Interop internal static extern bool ResetEvent(SafeWaitHandle handle); [DllImport(Interop.Libraries.Kernel32, EntryPoint = "CreateEventExW", SetLastError = true, CharSet = CharSet.Unicode)] - internal static extern SafeWaitHandle CreateEventEx(IntPtr lpSecurityAttributes, string name, uint flags, uint desiredAccess); + internal static extern SafeWaitHandle CreateEventEx(IntPtr lpSecurityAttributes, string? name, uint flags, uint desiredAccess); [DllImport(Interop.Libraries.Kernel32, EntryPoint = "OpenEventW", SetLastError = true, CharSet = CharSet.Unicode)] internal static extern SafeWaitHandle OpenEvent(uint desiredAccess, bool inheritHandle, string name); diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Mutex.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Mutex.cs index cbb306e4f7..ed25668a00 100644 --- a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Mutex.cs +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Mutex.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Microsoft.Win32.SafeHandles; using System; using System.Runtime.InteropServices; @@ -16,7 +17,7 @@ internal static partial class Interop internal static extern SafeWaitHandle OpenMutex(uint desiredAccess, bool inheritHandle, string name); [DllImport(Interop.Libraries.Kernel32, EntryPoint = "CreateMutexExW", SetLastError = true, CharSet = CharSet.Unicode)] - internal static extern SafeWaitHandle CreateMutexEx(IntPtr lpMutexAttributes, string name, uint flags, uint desiredAccess); + internal static extern SafeWaitHandle CreateMutexEx(IntPtr lpMutexAttributes, string? name, uint flags, uint desiredAccess); [DllImport(Interop.Libraries.Kernel32, SetLastError = true)] internal static extern bool ReleaseMutex(SafeWaitHandle handle); diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Semaphore.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Semaphore.cs index 94648a7077..f453a255bd 100644 --- a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Semaphore.cs +++ b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Semaphore.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Microsoft.Win32.SafeHandles; using System; using System.Runtime.InteropServices; @@ -14,7 +15,7 @@ internal static partial class Interop internal static extern SafeWaitHandle OpenSemaphore(uint desiredAccess, bool inheritHandle, string name); [DllImport(Libraries.Kernel32, EntryPoint = "CreateSemaphoreExW", SetLastError = true, CharSet = CharSet.Unicode)] - internal static extern SafeWaitHandle CreateSemaphoreEx(IntPtr lpSecurityAttributes, int initialCount, int maximumCount, string name, uint flags, uint desiredAccess); + internal static extern SafeWaitHandle CreateSemaphoreEx(IntPtr lpSecurityAttributes, int initialCount, int maximumCount, string? name, uint flags, uint desiredAccess); [DllImport(Interop.Libraries.Kernel32, SetLastError = true)] internal static extern bool ReleaseSemaphore(SafeWaitHandle handle, int releaseCount, out int previousCount); diff --git a/src/System.Private.CoreLib/shared/System/AccessViolationException.cs b/src/System.Private.CoreLib/shared/System/AccessViolationException.cs index a66f2a892e..357930898c 100644 --- a/src/System.Private.CoreLib/shared/System/AccessViolationException.cs +++ b/src/System.Private.CoreLib/shared/System/AccessViolationException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System; using System.Runtime.Serialization; @@ -26,13 +27,13 @@ namespace System HResult = HResults.E_POINTER; } - public AccessViolationException(string message) + public AccessViolationException(string? message) : base(message) { HResult = HResults.E_POINTER; } - public AccessViolationException(string message, Exception innerException) + public AccessViolationException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.E_POINTER; diff --git a/src/System.Private.CoreLib/shared/System/AggregateException.cs b/src/System.Private.CoreLib/shared/System/AggregateException.cs index 048005c479..d0043cfc90 100644 --- a/src/System.Private.CoreLib/shared/System/AggregateException.cs +++ b/src/System.Private.CoreLib/shared/System/AggregateException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -41,7 +42,7 @@ namespace System /// a specified error message. /// </summary> /// <param name="message">The error message that explains the reason for the exception.</param> - public AggregateException(string message) + public AggregateException(string? message) : base(message) { m_innerExceptions = new ReadOnlyCollection<Exception>(Array.Empty<Exception>()); @@ -55,7 +56,7 @@ namespace System /// <param name="innerException">The exception that is the cause of the current exception.</param> /// <exception cref="T:System.ArgumentNullException">The <paramref name="innerException"/> argument /// is null.</exception> - public AggregateException(string message, Exception innerException) + public AggregateException(string? message, Exception innerException) : base(message, innerException) { if (innerException == null) @@ -104,10 +105,10 @@ namespace System /// is null.</exception> /// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptions"/> is /// null.</exception> - public AggregateException(string message, IEnumerable<Exception> innerExceptions) + public AggregateException(string? message, IEnumerable<Exception> innerExceptions) // If it's already an IList, pass that along (a defensive copy will be made in the delegated ctor). If it's null, just pass along // null typed correctly. Otherwise, create an IList from the enumerable and pass that along. - : this(message, innerExceptions as IList<Exception> ?? (innerExceptions == null ? (List<Exception>)null : new List<Exception>(innerExceptions))) + : this(message, innerExceptions as IList<Exception> ?? (innerExceptions == null ? (List<Exception>)null! : new List<Exception>(innerExceptions))) { } @@ -121,7 +122,7 @@ namespace System /// is null.</exception> /// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptions"/> is /// null.</exception> - public AggregateException(string message, params Exception[] innerExceptions) : + public AggregateException(string? message, params Exception[] innerExceptions) : this(message, (IList<Exception>)innerExceptions) { } @@ -135,7 +136,7 @@ namespace System /// is null.</exception> /// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptions"/> is /// null.</exception> - private AggregateException(string message, IList<Exception> innerExceptions) + private AggregateException(string? message, IList<Exception> innerExceptions) : base(message, innerExceptions != null && innerExceptions.Count > 0 ? innerExceptions[0] : null) { if (innerExceptions == null) @@ -195,7 +196,7 @@ namespace System // null typed correctly. Otherwise, create an IList from the enumerable and pass that along. : this(message, innerExceptionInfos as IList<ExceptionDispatchInfo> ?? (innerExceptionInfos == null ? - (List<ExceptionDispatchInfo>)null : + (List<ExceptionDispatchInfo>)null! : new List<ExceptionDispatchInfo>(innerExceptionInfos))) { } @@ -257,7 +258,7 @@ namespace System throw new ArgumentNullException(nameof(info)); } - Exception[] innerExceptions = info.GetValue("InnerExceptions", typeof(Exception[])) as Exception[]; + Exception[]? innerExceptions = info.GetValue("InnerExceptions", typeof(Exception[])) as Exception[]; if (innerExceptions == null) { throw new SerializationException(SR.AggregateException_DeserializationFailure); @@ -292,14 +293,14 @@ namespace System // Returns the first inner AggregateException that contains more or less than one inner exception // Recursively traverse the inner exceptions as long as the inner exception of type AggregateException and has only one inner exception - Exception back = this; - AggregateException backAsAggregate = this; + Exception? back = this; + AggregateException? backAsAggregate = this; while (backAsAggregate != null && backAsAggregate.InnerExceptions.Count == 1) { - back = back.InnerException; + back = back!.InnerException; backAsAggregate = back as AggregateException; } - return back; + return back!; } /// <summary> @@ -338,7 +339,7 @@ namespace System throw new ArgumentNullException(nameof(predicate)); } - List<Exception> unhandledExceptions = null; + List<Exception>? unhandledExceptions = null; for (int i = 0; i < m_innerExceptions.Count; i++) { // If the exception was not handled, lazily allocate a list of unhandled diff --git a/src/System.Private.CoreLib/shared/System/ApplicationException.cs b/src/System.Private.CoreLib/shared/System/ApplicationException.cs index cac29196bf..5042b112cd 100644 --- a/src/System.Private.CoreLib/shared/System/ApplicationException.cs +++ b/src/System.Private.CoreLib/shared/System/ApplicationException.cs @@ -12,6 +12,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -39,13 +40,13 @@ namespace System // message, its HRESULT set to COR_E_APPLICATION, // and its ExceptionInfo reference set to null. // - public ApplicationException(string message) + public ApplicationException(string? message) : base(message) { HResult = HResults.COR_E_APPLICATION; } - public ApplicationException(string message, Exception innerException) + public ApplicationException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_APPLICATION; diff --git a/src/System.Private.CoreLib/shared/System/ArgumentException.cs b/src/System.Private.CoreLib/shared/System/ArgumentException.cs index 5a918063e7..be7ffbe7fa 100644 --- a/src/System.Private.CoreLib/shared/System/ArgumentException.cs +++ b/src/System.Private.CoreLib/shared/System/ArgumentException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Globalization; using System.Runtime.Serialization; @@ -23,7 +24,7 @@ namespace System [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class ArgumentException : SystemException { - private string _paramName; + private string? _paramName; // Creates a new ArgumentException with its message // string set to the empty string. @@ -36,26 +37,26 @@ namespace System // Creates a new ArgumentException with its message // string set to message. // - public ArgumentException(string message) + public ArgumentException(string? message) : base(message) { HResult = HResults.COR_E_ARGUMENT; } - public ArgumentException(string message, Exception innerException) + public ArgumentException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_ARGUMENT; } - public ArgumentException(string message, string paramName, Exception innerException) + public ArgumentException(string? message, string? paramName, Exception? innerException) : base(message, innerException) { _paramName = paramName; HResult = HResults.COR_E_ARGUMENT; } - public ArgumentException(string message, string paramName) + public ArgumentException(string? message, string? paramName) : base(message) { _paramName = paramName; @@ -89,7 +90,7 @@ namespace System } } - public virtual string ParamName + public virtual string? ParamName { get { return _paramName; } } diff --git a/src/System.Private.CoreLib/shared/System/ArgumentNullException.cs b/src/System.Private.CoreLib/shared/System/ArgumentNullException.cs index edc38f2a4c..206c1a055b 100644 --- a/src/System.Private.CoreLib/shared/System/ArgumentNullException.cs +++ b/src/System.Private.CoreLib/shared/System/ArgumentNullException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -30,19 +31,19 @@ namespace System HResult = HResults.E_POINTER; } - public ArgumentNullException(string paramName) + public ArgumentNullException(string? paramName) : base(SR.ArgumentNull_Generic, paramName) { HResult = HResults.E_POINTER; } - public ArgumentNullException(string message, Exception innerException) + public ArgumentNullException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.E_POINTER; } - public ArgumentNullException(string paramName, string message) + public ArgumentNullException(string? paramName, string? message) : base(message, paramName) { HResult = HResults.E_POINTER; diff --git a/src/System.Private.CoreLib/shared/System/ArgumentOutOfRangeException.cs b/src/System.Private.CoreLib/shared/System/ArgumentOutOfRangeException.cs index 2c1941b62b..7ca9085c63 100644 --- a/src/System.Private.CoreLib/shared/System/ArgumentOutOfRangeException.cs +++ b/src/System.Private.CoreLib/shared/System/ArgumentOutOfRangeException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Globalization; using System.Runtime.Serialization; @@ -22,7 +23,7 @@ namespace System [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class ArgumentOutOfRangeException : ArgumentException { - private object _actualValue; + private object? _actualValue; // Creates a new ArgumentOutOfRangeException with its message // string set to a default message explaining an argument was out of range. @@ -32,19 +33,19 @@ namespace System HResult = HResults.COR_E_ARGUMENTOUTOFRANGE; } - public ArgumentOutOfRangeException(string paramName) + public ArgumentOutOfRangeException(string? paramName) : base(SR.Arg_ArgumentOutOfRangeException, paramName) { HResult = HResults.COR_E_ARGUMENTOUTOFRANGE; } - public ArgumentOutOfRangeException(string paramName, string message) + public ArgumentOutOfRangeException(string? paramName, string? message) : base(message, paramName) { HResult = HResults.COR_E_ARGUMENTOUTOFRANGE; } - public ArgumentOutOfRangeException(string message, Exception innerException) + public ArgumentOutOfRangeException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_ARGUMENTOUTOFRANGE; @@ -53,7 +54,7 @@ namespace System // We will not use this in the classlibs, but we'll provide it for // anyone that's really interested so they don't have to stick a bunch // of printf's in their code. - public ArgumentOutOfRangeException(string paramName, object actualValue, string message) + public ArgumentOutOfRangeException(string? paramName, object? actualValue, string? message) : base(message, paramName) { _actualValue = actualValue; @@ -92,7 +93,7 @@ namespace System // Note - we don't set this anywhere in the class libraries in // version 1, but it might come in handy for other developers who // want to avoid sticking printf's in their code. - public virtual object ActualValue + public virtual object? ActualValue { get { return _actualValue; } } diff --git a/src/System.Private.CoreLib/shared/System/ArithmeticException.cs b/src/System.Private.CoreLib/shared/System/ArithmeticException.cs index 46492cab56..5521c39a2f 100644 --- a/src/System.Private.CoreLib/shared/System/ArithmeticException.cs +++ b/src/System.Private.CoreLib/shared/System/ArithmeticException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -34,13 +35,13 @@ namespace System // message, its HRESULT set to COR_E_ARITHMETIC, // and its ExceptionInfo reference set to null. // - public ArithmeticException(string message) + public ArithmeticException(string? message) : base(message) { HResult = HResults.COR_E_ARITHMETIC; } - public ArithmeticException(string message, Exception innerException) + public ArithmeticException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_ARITHMETIC; diff --git a/src/System.Private.CoreLib/shared/System/ArrayTypeMismatchException.cs b/src/System.Private.CoreLib/shared/System/ArrayTypeMismatchException.cs index 2f60fd4ea5..c2a6244e50 100644 --- a/src/System.Private.CoreLib/shared/System/ArrayTypeMismatchException.cs +++ b/src/System.Private.CoreLib/shared/System/ArrayTypeMismatchException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -34,13 +35,13 @@ namespace System // message, its HRESULT set to COR_E_ARRAYTYPEMISMATCH, // and its ExceptionInfo reference set to null. // - public ArrayTypeMismatchException(string message) + public ArrayTypeMismatchException(string? message) : base(message) { HResult = HResults.COR_E_ARRAYTYPEMISMATCH; } - public ArrayTypeMismatchException(string message, Exception innerException) + public ArrayTypeMismatchException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_ARRAYTYPEMISMATCH; diff --git a/src/System.Private.CoreLib/shared/System/BadImageFormatException.cs b/src/System.Private.CoreLib/shared/System/BadImageFormatException.cs index c8cb65c64a..1839231932 100644 --- a/src/System.Private.CoreLib/shared/System/BadImageFormatException.cs +++ b/src/System.Private.CoreLib/shared/System/BadImageFormatException.cs @@ -11,6 +11,7 @@ ** ===========================================================*/ +#nullable enable using System.Globalization; using System.IO; using System.Runtime.Serialization; @@ -21,8 +22,8 @@ namespace System [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public partial class BadImageFormatException : SystemException { - private string _fileName; // The name of the corrupt PE file. - private string _fusionLog = null; // fusion log (when applicable) + private string? _fileName; // The name of the corrupt PE file. + private string? _fusionLog; // fusion log (when applicable) public BadImageFormatException() : base(SR.Arg_BadImageFormatException) @@ -30,25 +31,25 @@ namespace System HResult = HResults.COR_E_BADIMAGEFORMAT; } - public BadImageFormatException(string message) + public BadImageFormatException(string? message) : base(message) { HResult = HResults.COR_E_BADIMAGEFORMAT; } - public BadImageFormatException(string message, Exception inner) + public BadImageFormatException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_BADIMAGEFORMAT; } - public BadImageFormatException(string message, string fileName) : base(message) + public BadImageFormatException(string? message, string? fileName) : base(message) { HResult = HResults.COR_E_BADIMAGEFORMAT; _fileName = fileName; } - public BadImageFormatException(string message, string fileName, Exception inner) + public BadImageFormatException(string? message, string? fileName, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_BADIMAGEFORMAT; @@ -74,7 +75,7 @@ namespace System get { SetMessageField(); - return _message; + return _message!; } } @@ -91,7 +92,7 @@ namespace System } } - public string FileName + public string? FileName { get { return _fileName; } } @@ -121,7 +122,7 @@ namespace System return s; } - public string FusionLog + public string? FusionLog { get { return _fusionLog; } } diff --git a/src/System.Private.CoreLib/shared/System/Buffers/ArrayPool.cs b/src/System.Private.CoreLib/shared/System/Buffers/ArrayPool.cs index 5e01399a33..8e67e22599 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/ArrayPool.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/ArrayPool.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers { /// <summary> diff --git a/src/System.Private.CoreLib/shared/System/Buffers/ArrayPoolEventSource.cs b/src/System.Private.CoreLib/shared/System/Buffers/ArrayPoolEventSource.cs index d0563c4977..9ae0e3d913 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/ArrayPoolEventSource.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/ArrayPoolEventSource.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics.Tracing; namespace System.Buffers diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Binary/Reader.cs b/src/System.Private.CoreLib/shared/System/Buffers/Binary/Reader.cs index 49d0a2db42..f4a8142731 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Binary/Reader.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Binary/Reader.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Numerics; using System.Runtime.CompilerServices; diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Binary/ReaderBigEndian.cs b/src/System.Private.CoreLib/shared/System/Buffers/Binary/ReaderBigEndian.cs index b45dd8913d..31745dd3cc 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Binary/ReaderBigEndian.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Binary/ReaderBigEndian.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Binary/ReaderLittleEndian.cs b/src/System.Private.CoreLib/shared/System/Buffers/Binary/ReaderLittleEndian.cs index bd832f8995..e4a03c013a 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Binary/ReaderLittleEndian.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Binary/ReaderLittleEndian.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Binary/WriterBigEndian.cs b/src/System.Private.CoreLib/shared/System/Buffers/Binary/WriterBigEndian.cs index 78be9b5a03..ea56c78a4b 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Binary/WriterBigEndian.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Binary/WriterBigEndian.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Binary/WriterLittleEndian.cs b/src/System.Private.CoreLib/shared/System/Buffers/Binary/WriterLittleEndian.cs index 5d63ee5f0b..201ead0e9f 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Binary/WriterLittleEndian.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Binary/WriterLittleEndian.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/System/Buffers/ConfigurableArrayPool.cs b/src/System.Private.CoreLib/shared/System/Buffers/ConfigurableArrayPool.cs index f7b6034d20..dd49d8a250 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/ConfigurableArrayPool.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/ConfigurableArrayPool.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Threading; @@ -74,7 +75,7 @@ namespace System.Buffers } var log = ArrayPoolEventSource.Log; - T[] buffer = null; + T[]? buffer = null; int index = Utilities.SelectBucketIndex(minimumLength); if (index < _buckets.Length) @@ -163,7 +164,7 @@ namespace System.Buffers private sealed class Bucket { internal readonly int _bufferLength; - private readonly T[][] _buffers; + private readonly T[]?[] _buffers; private readonly int _poolId; private SpinLock _lock; // do not make this readonly; it's a mutable struct @@ -184,10 +185,10 @@ namespace System.Buffers internal int Id => GetHashCode(); /// <summary>Takes an array from the bucket. If the bucket is empty, returns null.</summary> - internal T[] Rent() + internal T[]? Rent() { - T[][] buffers = _buffers; - T[] buffer = null; + T[]?[] buffers = _buffers; + T[]? buffer = null; // While holding the lock, grab whatever is at the next available index and // update the index. We do as little work as possible while holding the spin diff --git a/src/System.Private.CoreLib/shared/System/Buffers/IMemoryOwner.cs b/src/System.Private.CoreLib/shared/System/Buffers/IMemoryOwner.cs index 44f16c5827..19d01166c6 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/IMemoryOwner.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/IMemoryOwner.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers { /// <summary> diff --git a/src/System.Private.CoreLib/shared/System/Buffers/IPinnable.cs b/src/System.Private.CoreLib/shared/System/Buffers/IPinnable.cs index 623e716a05..b8b49d4cd1 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/IPinnable.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/IPinnable.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers { /// <summary> diff --git a/src/System.Private.CoreLib/shared/System/Buffers/MemoryHandle.cs b/src/System.Private.CoreLib/shared/System/Buffers/MemoryHandle.cs index b218534c52..23325d5d6e 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/MemoryHandle.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/MemoryHandle.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; namespace System.Buffers @@ -13,7 +14,7 @@ namespace System.Buffers { private void* _pointer; private GCHandle _handle; - private IPinnable _pinnable; + private IPinnable? _pinnable; /// <summary> /// Creates a new memory handle for the memory. @@ -22,7 +23,7 @@ namespace System.Buffers /// <param name="pinnable">reference to manually managed object, or default if there is no memory manager</param> /// <param name="handle">handle used to pin array buffers</param> [CLSCompliant(false)] - public MemoryHandle(void* pointer, GCHandle handle = default, IPinnable pinnable = default) + public MemoryHandle(void* pointer, GCHandle handle = default, IPinnable? pinnable = default) { _pointer = pointer; _handle = handle; diff --git a/src/System.Private.CoreLib/shared/System/Buffers/MemoryManager.cs b/src/System.Private.CoreLib/shared/System/Buffers/MemoryManager.cs index 1b235b538e..5c4061e9b4 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/MemoryManager.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/MemoryManager.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; namespace System.Buffers diff --git a/src/System.Private.CoreLib/shared/System/Buffers/OperationStatus.cs b/src/System.Private.CoreLib/shared/System/Buffers/OperationStatus.cs index e9ddcab571..c8235f7cc4 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/OperationStatus.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/OperationStatus.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers { /// <summary> diff --git a/src/System.Private.CoreLib/shared/System/Buffers/StandardFormat.cs b/src/System.Private.CoreLib/shared/System/Buffers/StandardFormat.cs index 83014d06b0..5675f4ced3 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/StandardFormat.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/StandardFormat.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Buffers @@ -79,7 +80,7 @@ namespace System.Buffers /// <summary> /// Converts a classic .NET format string into a StandardFormat /// </summary> - public static StandardFormat Parse(string format) => format == null ? default : Parse(format.AsSpan()); + public static StandardFormat Parse(string? format) => format == null ? default : Parse(format.AsSpan()); /// <summary> /// Tries to convert a <see cref="ReadOnlySpan{Char}"/> into a StandardFormat. A return value indicates whether the conversion succeeded or failed. @@ -129,7 +130,7 @@ namespace System.Buffers /// <summary> /// Returns true if both the Symbol and Precision are equal. /// </summary> - public override bool Equals(object obj) => obj is StandardFormat other && Equals(other); + public override bool Equals(object? obj) => obj is StandardFormat other && Equals(other); /// <summary> /// Compute a hash code. diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs index ac45347a5e..a7a1fc24a8 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Constants.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Constants.cs index e2f70f0b10..25880fcf95 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Constants.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Constants.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { internal static partial class Utf8Constants diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/FormattingHelpers.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/FormattingHelpers.cs index 1b30d5f013..a9f185aae9 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/FormattingHelpers.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/FormattingHelpers.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.CompilerServices; diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Boolean.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Boolean.cs index 31bb6cae55..bc6b894be7 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Boolean.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Boolean.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers.Binary; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.G.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.G.cs index 7c4a2e342d..2290a10726 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.G.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.G.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Formatter diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.L.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.L.cs index 699f91f39c..e817064bf8 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.L.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.L.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Formatter diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.O.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.O.cs index d9b7b181bc..706c634ddd 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.O.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.O.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Formatter diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.R.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.R.cs index dd9ec459b7..aed0795b39 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.R.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.R.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Formatter diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.cs index 046885d162..31da577c82 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Formatter diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.E.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.E.cs index 89b54f2fd5..859adea1ca 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.E.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.E.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.F.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.F.cs index 51bc20b8d2..1efe257f54 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.F.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.F.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.G.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.G.cs index b867eaec1a..c737749394 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.G.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.G.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.cs index bb93b992ef..72b9fca51b 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Float.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Float.cs index 96e70bada9..c4d70b4da9 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Float.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Float.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Globalization; using System.Text; diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Guid.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Guid.cs index 479f1dd1cb..61085b8924 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Guid.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Guid.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.D.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.D.cs index 7532f0cf15..88f4c16028 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.D.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.D.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.Default.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.Default.cs index 046f5baf66..1c213e3879 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.Default.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.Default.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.CompilerServices; diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.N.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.N.cs index 1c01b8d60d..542bd1eeb7 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.N.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.N.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.cs index fcd20b312d..025fc8b45e 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.D.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.D.cs index 9cb8d64bc0..78542eb4cf 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.D.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.D.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { /// <summary> diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.Default.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.Default.cs index d83591ed98..5d8f1f0118 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.Default.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.Default.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.CompilerServices; diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.N.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.N.cs index ce21c0d3dd..b6caaa6cf9 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.N.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.N.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { /// <summary> diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.X.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.X.cs index 4cf4d52b5c..1db31dfe59 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.X.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.X.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { /// <summary> diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.cs index 0040c5075a..b531ba714d 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs index 3b83fb7512..2024551ff9 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { /// <summary> diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.TimeSpan.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.TimeSpan.cs index 38bb35f7df..b41cb75d0e 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.TimeSpan.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Formatter/Utf8Formatter.TimeSpan.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/ParserHelpers.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/ParserHelpers.cs index f440182bf9..7630277464 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/ParserHelpers.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/ParserHelpers.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; namespace System.Buffers.Text @@ -65,7 +66,7 @@ namespace System.Buffers.Text // // Enable use of ThrowHelper from TryParse() routines without introducing dozens of non-code-coveraged "value= default; bytesConsumed = 0; return false" boilerplate. // - public static bool TryParseThrowFormatException<T>(out T value, out int bytesConsumed) + public static bool TryParseThrowFormatException<T>(out T value, out int bytesConsumed) where T : struct { value = default; return TryParseThrowFormatException(out bytesConsumed); diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Boolean.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Boolean.cs index 3b039bae25..56d88e9d46 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Boolean.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Boolean.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers.Binary; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.Default.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.Default.cs index 73578ea88c..fdf79985ee 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.Default.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.Default.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.G.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.G.cs index 6e8edbcbdf..d930831b60 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.G.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.G.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.Helpers.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.Helpers.cs index d2fb06829a..0d62d81883 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.Helpers.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.Helpers.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.O.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.O.cs index 8d2c681f68..9ea3fa34f1 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.O.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.O.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.R.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.R.cs index 316bee01b4..7a16b07e18 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.R.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.R.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.cs index 35ad716705..37070ef5cf 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Decimal.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Decimal.cs index 5ed385a71b..84bc7797de 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Decimal.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Decimal.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Float.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Float.cs index f68945cb5a..c2f84dd2b4 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Float.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Float.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers.Binary; namespace System.Buffers.Text @@ -113,7 +114,7 @@ namespace System.Buffers.Text // // Assuming the text doesn't look like a normal floating point, we attempt to parse it as one the special floating point values. // - private static bool TryParseAsSpecialFloatingPoint<T>(ReadOnlySpan<byte> source, T positiveInfinity, T negativeInfinity, T nan, out T value, out int bytesConsumed) + private static bool TryParseAsSpecialFloatingPoint<T>(ReadOnlySpan<byte> source, T positiveInfinity, T negativeInfinity, T nan, out T value, out int bytesConsumed) where T : struct { int srcIndex = 0; int remaining = source.Length; diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Guid.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Guid.cs index f0a99dd522..18aaf64212 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Guid.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Guid.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.D.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.D.cs index bf1871a1c9..fc9eb5ea25 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.D.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.D.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.N.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.N.cs index fd8ce572f2..8cf986b18e 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.N.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.N.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.cs index 2e861b1cfd..0ee5b7e3f9 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Internal.Runtime.CompilerServices; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.D.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.D.cs index 46753f5c57..675231b26f 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.D.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.D.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.N.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.N.cs index 2db20c1270..72f2831e62 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.N.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.N.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { // diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.X.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.X.cs index 7e7867a56f..1042faece2 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.X.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.X.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.cs index 7c4e94e56f..f420bf1818 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Number.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Number.cs index 799a3fe6a7..2727747d34 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Number.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.Number.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.BigG.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.BigG.cs index 6bcb4d5277..e05523c45f 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.BigG.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.BigG.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.C.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.C.cs index d0a28969be..94d539fa88 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.C.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.C.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.LittleG.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.LittleG.cs index 19208b9eac..7172da4e0c 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.LittleG.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.LittleG.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.cs index b49cccb6a2..641a0b3f03 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpanSplitter.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpanSplitter.cs index 0c72d1f3a2..4340399ec9 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpanSplitter.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpanSplitter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Buffers.Text diff --git a/src/System.Private.CoreLib/shared/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs b/src/System.Private.CoreLib/shared/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs index 1a933a5014..5c5fd994ed 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs @@ -2,8 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Threading; using Internal.Runtime.CompilerServices; @@ -42,10 +44,10 @@ namespace System.Buffers /// An array of per-core array stacks. The slots are lazily initialized to avoid creating /// lots of overhead for unused array sizes. /// </summary> - private readonly PerCoreLockedStacks[] _buckets = new PerCoreLockedStacks[NumBuckets]; + private readonly PerCoreLockedStacks?[] _buckets = new PerCoreLockedStacks[NumBuckets]; /// <summary>A per-thread array of arrays, to cache one array per array size per thread.</summary> [ThreadStatic] - private static T[][] t_tlsBuckets; + private static T[]?[]? t_tlsBuckets; private int _callbackCreated; @@ -54,7 +56,8 @@ namespace System.Buffers /// <summary> /// Used to keep track of all thread local buckets for trimming if needed /// </summary> - private static readonly ConditionalWeakTable<T[][], object> s_allTlsBuckets = s_trimBuffers ? new ConditionalWeakTable<T[][], object>() : null; + private static readonly ConditionalWeakTable<T[]?[], object?>? s_allTlsBuckets = + s_trimBuffers ? new ConditionalWeakTable<T[]?[], object?>() : null; /// <summary>Initialize the pool.</summary> public TlsOverPerCoreLockedStacksArrayPool() @@ -94,7 +97,7 @@ namespace System.Buffers } ArrayPoolEventSource log = ArrayPoolEventSource.Log; - T[] buffer; + T[]? buffer; // Get the bucket number for the array length int bucketIndex = Utilities.SelectBucketIndex(minimumLength); @@ -103,7 +106,7 @@ namespace System.Buffers if (bucketIndex < _buckets.Length) { // First try to get it from TLS if possible. - T[][] tlsBuckets = t_tlsBuckets; + T[]?[]? tlsBuckets = t_tlsBuckets; if (tlsBuckets != null) { buffer = tlsBuckets[bucketIndex]; @@ -119,7 +122,7 @@ namespace System.Buffers } // We couldn't get a buffer from TLS, so try the global stack. - PerCoreLockedStacks b = _buckets[bucketIndex]; + PerCoreLockedStacks? b = _buckets[bucketIndex]; if (b != null) { buffer = b.TryPop(); @@ -185,13 +188,14 @@ namespace System.Buffers // if there was a previous one there, push that to the global stack. This // helps to keep LIFO access such that the most recently pushed stack will // be in TLS and the first to be popped next. - T[][] tlsBuckets = t_tlsBuckets; + T[]?[]? tlsBuckets = t_tlsBuckets; if (tlsBuckets == null) { t_tlsBuckets = tlsBuckets = new T[NumBuckets][]; tlsBuckets[bucketIndex] = array; if (s_trimBuffers) { + Debug.Assert(s_allTlsBuckets != null, "Should be non-null iff s_trimBuffers is true"); s_allTlsBuckets.Add(tlsBuckets, null); if (Interlocked.Exchange(ref _callbackCreated, 1) != 1) { @@ -201,7 +205,7 @@ namespace System.Buffers } else { - T[] prev = tlsBuckets[bucketIndex]; + T[]? prev = tlsBuckets[bucketIndex]; tlsBuckets[bucketIndex] = array; if (prev != null) @@ -222,6 +226,9 @@ namespace System.Buffers public bool Trim() { + Debug.Assert(s_trimBuffers); + Debug.Assert(s_allTlsBuckets != null); + int milliseconds = Environment.TickCount; MemoryPressure pressure = GetMemoryPressure(); @@ -229,7 +236,7 @@ namespace System.Buffers if (log.IsEnabled()) log.BufferTrimPoll(milliseconds, (int)pressure); - PerCoreLockedStacks[] perCoreBuckets = _buckets; + PerCoreLockedStacks?[] perCoreBuckets = _buckets; for (int i = 0; i < perCoreBuckets.Length; i++) { perCoreBuckets[i]?.Trim((uint)milliseconds, Id, pressure, _bucketArraySizes[i]); @@ -240,12 +247,12 @@ namespace System.Buffers // Under high pressure, release all thread locals if (log.IsEnabled()) { - foreach (KeyValuePair<T[][], object> tlsBuckets in s_allTlsBuckets) + foreach (KeyValuePair<T[]?[], object> tlsBuckets in s_allTlsBuckets) { - T[][] buckets = tlsBuckets.Key; + T[]?[] buckets = tlsBuckets.Key; for (int i = 0; i < buckets.Length; i++) { - T[] buffer = Interlocked.Exchange(ref buckets[i], null); + T[]? buffer = Interlocked.Exchange(ref buckets[i], null); if (buffer != null) { // As we don't want to take a perf hit in the rent path it @@ -257,9 +264,9 @@ namespace System.Buffers } else { - foreach (KeyValuePair<T[][], object> tlsBuckets in s_allTlsBuckets) + foreach (KeyValuePair<T[]?[], object?> tlsBuckets in s_allTlsBuckets) { - T[][] buckets = tlsBuckets.Key; + T[]?[] buckets = tlsBuckets.Key; Array.Clear(buckets, 0, buckets.Length); } } @@ -355,11 +362,11 @@ namespace System.Buffers /// <summary>Try to get an array from the stacks. If each is empty when it's tested, null will be returned.</summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public T[] TryPop() + public T[]? TryPop() { // Try to pop from the associated stack first. If that fails, // round-robin through the other stacks. - T[] arr; + T[]? arr; LockedStack[] stacks = _perCoreStacks; int index = Thread.GetCurrentProcessorId() % stacks.Length; for (int i = 0; i < stacks.Length; i++) @@ -383,7 +390,7 @@ namespace System.Buffers /// <summary>Provides a simple stack of arrays, protected by a lock.</summary> private sealed class LockedStack { - private readonly T[][] _arrays = new T[MaxBuffersPerArraySizePerCore][]; + private readonly T[]?[] _arrays = new T[MaxBuffersPerArraySizePerCore][]; private int _count; private uint _firstStackItemMS; @@ -408,9 +415,9 @@ namespace System.Buffers } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public T[] TryPop() + public T[]? TryPop() { - T[] arr = null; + T[]? arr = null; Monitor.Enter(this); if (_count > 0) { @@ -473,7 +480,8 @@ namespace System.Buffers while (_count > 0 && trimCount-- > 0) { - T[] array = _arrays[--_count]; + T[]? array = _arrays[--_count]; + Debug.Assert(array != null, "No nulls should have been present in slots < _count."); _arrays[_count] = null; if (log.IsEnabled()) diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Utilities.cs b/src/System.Private.CoreLib/shared/System/Buffers/Utilities.cs index 7e1caa039b..c49555a6e5 100644 --- a/src/System.Private.CoreLib/shared/System/Buffers/Utilities.cs +++ b/src/System.Private.CoreLib/shared/System/Buffers/Utilities.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; diff --git a/src/System.Private.CoreLib/shared/System/CannotUnloadAppDomainException.cs b/src/System.Private.CoreLib/shared/System/CannotUnloadAppDomainException.cs index 9a4fb1437a..450a54c96b 100644 --- a/src/System.Private.CoreLib/shared/System/CannotUnloadAppDomainException.cs +++ b/src/System.Private.CoreLib/shared/System/CannotUnloadAppDomainException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System @@ -20,13 +21,13 @@ namespace System HResult = COR_E_CANNOTUNLOADAPPDOMAIN; } - public CannotUnloadAppDomainException(string message) + public CannotUnloadAppDomainException(string? message) : base(message) { HResult = COR_E_CANNOTUNLOADAPPDOMAIN; } - public CannotUnloadAppDomainException(string message, Exception innerException) + public CannotUnloadAppDomainException(string? message, Exception? innerException) : base(message, innerException) { HResult = COR_E_CANNOTUNLOADAPPDOMAIN; diff --git a/src/System.Private.CoreLib/shared/System/Collections/Generic/KeyNotFoundException.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/KeyNotFoundException.cs index 3990e13784..75f3e91c07 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/Generic/KeyNotFoundException.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/KeyNotFoundException.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +#nullable enable using System.Runtime.Serialization; namespace System.Collections.Generic @@ -17,13 +17,13 @@ namespace System.Collections.Generic HResult = HResults.COR_E_KEYNOTFOUND; } - public KeyNotFoundException(string message) + public KeyNotFoundException(string? message) : base(message) { HResult = HResults.COR_E_KEYNOTFOUND; } - public KeyNotFoundException(string message, Exception innerException) + public KeyNotFoundException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_KEYNOTFOUND; diff --git a/src/System.Private.CoreLib/shared/System/DataMisalignedException.cs b/src/System.Private.CoreLib/shared/System/DataMisalignedException.cs index 940407fc57..8c2618458a 100644 --- a/src/System.Private.CoreLib/shared/System/DataMisalignedException.cs +++ b/src/System.Private.CoreLib/shared/System/DataMisalignedException.cs @@ -9,6 +9,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -23,13 +24,13 @@ namespace System HResult = HResults.COR_E_DATAMISALIGNED; } - public DataMisalignedException(string message) + public DataMisalignedException(string? message) : base(message) { HResult = HResults.COR_E_DATAMISALIGNED; } - public DataMisalignedException(string message, Exception innerException) + public DataMisalignedException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_DATAMISALIGNED; diff --git a/src/System.Private.CoreLib/shared/System/Delegate.cs b/src/System.Private.CoreLib/shared/System/Delegate.cs index d4db0f2dff..1e8b8c967a 100644 --- a/src/System.Private.CoreLib/shared/System/Delegate.cs +++ b/src/System.Private.CoreLib/shared/System/Delegate.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; @@ -16,7 +17,7 @@ namespace System public virtual object Clone() => MemberwiseClone(); - public static Delegate Combine(Delegate a, Delegate b) + public static Delegate? Combine(Delegate? a, Delegate? b) { if (a is null) return b; @@ -24,35 +25,35 @@ namespace System return a.CombineImpl(b); } - public static Delegate Combine(params Delegate[] delegates) + public static Delegate? Combine(params Delegate?[]? delegates) { - if (delegates is null || delegates.Length == 0) + if (delegates == null || delegates.Length == 0) return null; - Delegate d = delegates [0]; + Delegate? d = delegates[0]; for (int i = 1; i < delegates.Length; i++) d = Combine(d, delegates[i]); return d; } - protected virtual Delegate CombineImpl(Delegate d) => throw new MulticastNotSupportedException(SR.Multicast_Combine); + protected virtual Delegate CombineImpl(Delegate? d) => throw new MulticastNotSupportedException(SR.Multicast_Combine); // V2 api: Creates open or closed delegates to static or instance methods - relaxed signature checking allowed. - public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method) => CreateDelegate(type, firstArgument, method, throwOnBindFailure: true); + public static Delegate CreateDelegate(Type type, object? firstArgument, MethodInfo method) => CreateDelegate(type, firstArgument, method, throwOnBindFailure: true)!; // V1 api: Creates open delegates to static or instance methods - relaxed signature checking allowed. - public static Delegate CreateDelegate(Type type, MethodInfo method) => CreateDelegate(type, method, throwOnBindFailure: true); + public static Delegate CreateDelegate(Type type, MethodInfo method) => CreateDelegate(type, method, throwOnBindFailure: true)!; // V1 api: Creates closed delegates to instance methods only, relaxed signature checking disallowed. - public static Delegate CreateDelegate(Type type, object target, string method) => CreateDelegate(type, target, method, ignoreCase: false, throwOnBindFailure: true); - public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase) => CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure: true); + public static Delegate CreateDelegate(Type type, object target, string method) => CreateDelegate(type, target, method, ignoreCase: false, throwOnBindFailure: true)!; + public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase) => CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure: true)!; // V1 api: Creates open delegates to static methods only, relaxed signature checking disallowed. - public static Delegate CreateDelegate(Type type, Type target, string method) => CreateDelegate(type, target, method, ignoreCase: false, throwOnBindFailure: true); - public static Delegate CreateDelegate(Type type, Type target, string method, bool ignoreCase) => CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure: true); + public static Delegate CreateDelegate(Type type, Type target, string method) => CreateDelegate(type, target, method, ignoreCase: false, throwOnBindFailure: true)!; + public static Delegate CreateDelegate(Type type, Type target, string method, bool ignoreCase) => CreateDelegate(type, target, method, ignoreCase, throwOnBindFailure: true)!; - public object DynamicInvoke(params object[] args) + public object? DynamicInvoke(params object?[]? args) { return DynamicInvokeImpl(args); } @@ -63,9 +64,9 @@ namespace System public MethodInfo Method => GetMethodImpl(); - protected virtual Delegate RemoveImpl(Delegate d) => d.Equals(this) ? null : this; + protected virtual Delegate? RemoveImpl(Delegate d) => d.Equals(this) ? null : this; - public static Delegate Remove(Delegate source, Delegate value) + public static Delegate? Remove(Delegate? source, Delegate? value) { if (source == null) return null; @@ -79,9 +80,9 @@ namespace System return source.RemoveImpl(value); } - public static Delegate RemoveAll(Delegate source, Delegate value) + public static Delegate? RemoveAll(Delegate? source, Delegate? value) { - Delegate newDelegate = null; + Delegate? newDelegate = null; do { @@ -95,7 +96,7 @@ namespace System // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Delegate d1, Delegate d2) + public static bool operator ==(Delegate? d1, Delegate? d2) { // Test d2 first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test @@ -105,12 +106,12 @@ namespace System return (d1 is null) ? true : false; } - return ReferenceEquals(d2, d1) || d2.Equals((object)d1); + return ReferenceEquals(d2, d1) ? true : d2.Equals((object?)d1); } // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Delegate d1, Delegate d2) + public static bool operator !=(Delegate? d1, Delegate? d2) { // Test d2 first to allow branch elimination when inlined for not null checks (!= null) // so it can become a simple test @@ -123,4 +124,4 @@ namespace System return ReferenceEquals(d2, d1) ? false : !d2.Equals(d1); } } -}
\ No newline at end of file +} diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Contracts/ContractException.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Contracts/ContractException.cs index 6a29ac339e..9feaa23812 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Contracts/ContractException.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Contracts/ContractException.cs @@ -2,11 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Reflection; +#nullable enable using System.Runtime.Serialization; namespace System.Diagnostics.Contracts @@ -17,13 +13,13 @@ namespace System.Diagnostics.Contracts public sealed class ContractException : Exception { private readonly ContractFailureKind _kind; - private readonly string _userMessage; - private readonly string _condition; + private readonly string? _userMessage; + private readonly string? _condition; - public ContractFailureKind Kind { get { return _kind; } } - public string Failure { get { return this.Message; } } - public string UserMessage { get { return _userMessage; } } - public string Condition { get { return _condition; } } + public ContractFailureKind Kind => _kind; + public string Failure => this.Message; + public string? UserMessage => _userMessage; + public string? Condition => _condition; // Called by COM Interop, if we see COR_E_CODECONTRACTFAILED as an HRESULT. private ContractException() @@ -31,7 +27,7 @@ namespace System.Diagnostics.Contracts HResult = HResults.COR_E_CODECONTRACTFAILED; } - public ContractException(ContractFailureKind kind, string failure, string userMessage, string condition, Exception innerException) + public ContractException(ContractFailureKind kind, string? failure, string? userMessage, string? condition, Exception? innerException) : base(failure, innerException) { HResult = HResults.COR_E_CODECONTRACTFAILED; diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSourceException.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSourceException.cs index be1bf3940a..2e821ac10d 100644 --- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSourceException.cs +++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSourceException.cs @@ -2,8 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Resources; +#nullable enable using System.Runtime.Serialization; #if ES_BUILD_STANDALONE @@ -33,13 +32,13 @@ namespace System.Diagnostics.Tracing /// <summary> /// Initializes a new instance of the EventSourceException class with a specified error message. /// </summary> - public EventSourceException(string message) : base(message) { } + public EventSourceException(string? message) : base(message) { } /// <summary> /// Initializes a new instance of the EventSourceException class with a specified error message /// and a reference to the inner exception that is the cause of this exception. /// </summary> - public EventSourceException(string message, Exception innerException) : base(message, innerException) { } + public EventSourceException(string? message, Exception? innerException) : base(message, innerException) { } #if !ES_BUILD_PCL /// <summary> @@ -48,7 +47,7 @@ namespace System.Diagnostics.Tracing protected EventSourceException(SerializationInfo info, StreamingContext context) : base(info, context) { } #endif - internal EventSourceException(Exception innerException) : + internal EventSourceException(Exception? innerException) : base(SR.EventSource_ListenerWriteFailure, innerException) { } } } diff --git a/src/System.Private.CoreLib/shared/System/DivideByZeroException.cs b/src/System.Private.CoreLib/shared/System/DivideByZeroException.cs index 27f57414ff..8b04145eb3 100644 --- a/src/System.Private.CoreLib/shared/System/DivideByZeroException.cs +++ b/src/System.Private.CoreLib/shared/System/DivideByZeroException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -25,13 +26,13 @@ namespace System HResult = HResults.COR_E_DIVIDEBYZERO; } - public DivideByZeroException(string message) + public DivideByZeroException(string? message) : base(message) { HResult = HResults.COR_E_DIVIDEBYZERO; } - public DivideByZeroException(string message, Exception innerException) + public DivideByZeroException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_DIVIDEBYZERO; diff --git a/src/System.Private.CoreLib/shared/System/DllNotFoundException.cs b/src/System.Private.CoreLib/shared/System/DllNotFoundException.cs index bd29b8b13a..0165d1aa7c 100644 --- a/src/System.Private.CoreLib/shared/System/DllNotFoundException.cs +++ b/src/System.Private.CoreLib/shared/System/DllNotFoundException.cs @@ -12,6 +12,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -26,13 +27,13 @@ namespace System HResult = HResults.COR_E_DLLNOTFOUND; } - public DllNotFoundException(string message) + public DllNotFoundException(string? message) : base(message) { HResult = HResults.COR_E_DLLNOTFOUND; } - public DllNotFoundException(string message, Exception inner) + public DllNotFoundException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_DLLNOTFOUND; diff --git a/src/System.Private.CoreLib/shared/System/Double.cs b/src/System.Private.CoreLib/shared/System/Double.cs index 885f005a21..85b797ae8c 100644 --- a/src/System.Private.CoreLib/shared/System/Double.cs +++ b/src/System.Private.CoreLib/shared/System/Double.cs @@ -12,6 +12,7 @@ ** ===========================================================*/ +#nullable enable using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -122,7 +123,7 @@ namespace System // // Returns a value less than zero if this object // - public int CompareTo(object value) + public int CompareTo(object? value) { if (value == null) { @@ -159,7 +160,7 @@ namespace System // True if obj is another Double with the same value as the current instance. This is // a method of object equality, that only returns true if obj is also a double. - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (!(obj is double)) { @@ -242,22 +243,22 @@ namespace System return Number.FormatDouble(m_value, null, NumberFormatInfo.CurrentInfo); } - public string ToString(string format) + public string ToString(string? format) { return Number.FormatDouble(m_value, format, NumberFormatInfo.CurrentInfo); } - public string ToString(IFormatProvider provider) + public string ToString(IFormatProvider? provider) { return Number.FormatDouble(m_value, null, NumberFormatInfo.GetInstance(provider)); } - public string ToString(string format, IFormatProvider provider) + public string ToString(string? format, IFormatProvider? provider) { return Number.FormatDouble(m_value, format, NumberFormatInfo.GetInstance(provider)); } - public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format = default, IFormatProvider provider = null) + public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format = default, IFormatProvider? provider = null) { return Number.TryFormatDouble(m_value, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten); } @@ -275,13 +276,13 @@ namespace System return Number.ParseDouble(s, style, NumberFormatInfo.CurrentInfo); } - public static double Parse(string s, IFormatProvider provider) + public static double Parse(string s, IFormatProvider? provider) { if (s == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.s); return Number.ParseDouble(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.GetInstance(provider)); } - public static double Parse(string s, NumberStyles style, IFormatProvider provider) + public static double Parse(string s, NumberStyles style, IFormatProvider? provider) { NumberFormatInfo.ValidateParseStyleFloatingPoint(style); if (s == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.s); @@ -296,7 +297,7 @@ namespace System // PositiveInfinity or NegativeInfinity for a number that is too // large or too small. - public static double Parse(ReadOnlySpan<char> s, NumberStyles style = NumberStyles.Float | NumberStyles.AllowThousands, IFormatProvider provider = null) + public static double Parse(ReadOnlySpan<char> s, NumberStyles style = NumberStyles.Float | NumberStyles.AllowThousands, IFormatProvider? provider = null) { NumberFormatInfo.ValidateParseStyleFloatingPoint(style); return Number.ParseDouble(s, style, NumberFormatInfo.GetInstance(provider)); @@ -304,7 +305,7 @@ namespace System - public static bool TryParse(string s, out double result) + public static bool TryParse(string? s, out double result) { if (s == null) { @@ -320,7 +321,7 @@ namespace System return TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo, out result); } - public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out double result) + public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out double result) { NumberFormatInfo.ValidateParseStyleFloatingPoint(style); @@ -333,7 +334,7 @@ namespace System return TryParse((ReadOnlySpan<char>)s, style, NumberFormatInfo.GetInstance(provider), out result); } - public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider provider, out double result) + public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider, out double result) { NumberFormatInfo.ValidateParseStyleFloatingPoint(style); return TryParse(s, style, NumberFormatInfo.GetInstance(provider), out result); @@ -353,77 +354,77 @@ namespace System return TypeCode.Double; } - bool IConvertible.ToBoolean(IFormatProvider provider) + bool IConvertible.ToBoolean(IFormatProvider? provider) { return Convert.ToBoolean(m_value); } - char IConvertible.ToChar(IFormatProvider provider) + char IConvertible.ToChar(IFormatProvider? provider) { throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Double", "Char")); } - sbyte IConvertible.ToSByte(IFormatProvider provider) + sbyte IConvertible.ToSByte(IFormatProvider? provider) { return Convert.ToSByte(m_value); } - byte IConvertible.ToByte(IFormatProvider provider) + byte IConvertible.ToByte(IFormatProvider? provider) { return Convert.ToByte(m_value); } - short IConvertible.ToInt16(IFormatProvider provider) + short IConvertible.ToInt16(IFormatProvider? provider) { return Convert.ToInt16(m_value); } - ushort IConvertible.ToUInt16(IFormatProvider provider) + ushort IConvertible.ToUInt16(IFormatProvider? provider) { return Convert.ToUInt16(m_value); } - int IConvertible.ToInt32(IFormatProvider provider) + int IConvertible.ToInt32(IFormatProvider? provider) { return Convert.ToInt32(m_value); } - uint IConvertible.ToUInt32(IFormatProvider provider) + uint IConvertible.ToUInt32(IFormatProvider? provider) { return Convert.ToUInt32(m_value); } - long IConvertible.ToInt64(IFormatProvider provider) + long IConvertible.ToInt64(IFormatProvider? provider) { return Convert.ToInt64(m_value); } - ulong IConvertible.ToUInt64(IFormatProvider provider) + ulong IConvertible.ToUInt64(IFormatProvider? provider) { return Convert.ToUInt64(m_value); } - float IConvertible.ToSingle(IFormatProvider provider) + float IConvertible.ToSingle(IFormatProvider? provider) { return Convert.ToSingle(m_value); } - double IConvertible.ToDouble(IFormatProvider provider) + double IConvertible.ToDouble(IFormatProvider? provider) { return m_value; } - decimal IConvertible.ToDecimal(IFormatProvider provider) + decimal IConvertible.ToDecimal(IFormatProvider? provider) { return Convert.ToDecimal(m_value); } - DateTime IConvertible.ToDateTime(IFormatProvider provider) + DateTime IConvertible.ToDateTime(IFormatProvider? provider) { throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Double", "DateTime")); } - object IConvertible.ToType(Type type, IFormatProvider provider) + object IConvertible.ToType(Type type, IFormatProvider? provider) { return Convert.DefaultToType((IConvertible)this, type, provider); } diff --git a/src/System.Private.CoreLib/shared/System/DuplicateWaitObjectException.cs b/src/System.Private.CoreLib/shared/System/DuplicateWaitObjectException.cs index 8c21f15cb8..2fbe337f56 100644 --- a/src/System.Private.CoreLib/shared/System/DuplicateWaitObjectException.cs +++ b/src/System.Private.CoreLib/shared/System/DuplicateWaitObjectException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -29,19 +30,19 @@ namespace System HResult = HResults.COR_E_DUPLICATEWAITOBJECT; } - public DuplicateWaitObjectException(string parameterName) + public DuplicateWaitObjectException(string? parameterName) : base(SR.Arg_DuplicateWaitObjectException, parameterName) { HResult = HResults.COR_E_DUPLICATEWAITOBJECT; } - public DuplicateWaitObjectException(string parameterName, string message) + public DuplicateWaitObjectException(string? parameterName, string? message) : base(message, parameterName) { HResult = HResults.COR_E_DUPLICATEWAITOBJECT; } - public DuplicateWaitObjectException(string message, Exception innerException) + public DuplicateWaitObjectException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_DUPLICATEWAITOBJECT; diff --git a/src/System.Private.CoreLib/shared/System/EntryPointNotFoundException.cs b/src/System.Private.CoreLib/shared/System/EntryPointNotFoundException.cs index 606743aa1e..f88e07b93f 100644 --- a/src/System.Private.CoreLib/shared/System/EntryPointNotFoundException.cs +++ b/src/System.Private.CoreLib/shared/System/EntryPointNotFoundException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System; using System.Runtime.Serialization; @@ -26,13 +27,13 @@ namespace System HResult = HResults.COR_E_ENTRYPOINTNOTFOUND; } - public EntryPointNotFoundException(string message) + public EntryPointNotFoundException(string? message) : base(message) { HResult = HResults.COR_E_ENTRYPOINTNOTFOUND; } - public EntryPointNotFoundException(string message, Exception inner) + public EntryPointNotFoundException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_ENTRYPOINTNOTFOUND; diff --git a/src/System.Private.CoreLib/shared/System/Enum.cs b/src/System.Private.CoreLib/shared/System/Enum.cs index 94ca919a35..52ae2908e7 100644 --- a/src/System.Private.CoreLib/shared/System/Enum.cs +++ b/src/System.Private.CoreLib/shared/System/Enum.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Globalization; using System.Reflection; @@ -72,8 +73,7 @@ namespace System case CorElementType.ELEMENT_TYPE_U: return Unsafe.As<byte, UIntPtr>(ref data).ToString(); default: - Debug.Fail("Invalid primitive type"); - return null; + throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType); } } @@ -133,12 +133,12 @@ namespace System } } - internal static string GetEnumName(RuntimeType enumType, ulong ulValue) + internal static string? GetEnumName(RuntimeType enumType, ulong ulValue) { return GetEnumName(GetEnumInfo(enumType), ulValue); } - private static string GetEnumName(EnumInfo enumInfo, ulong ulValue) + private static string? GetEnumName(EnumInfo enumInfo, ulong ulValue) { int index = Array.BinarySearch(enumInfo.Values, ulValue); if (index >= 0) @@ -149,7 +149,7 @@ namespace System return null; // return null so the caller knows to .ToString() the input } - private static string InternalFormat(RuntimeType enumType, ulong value) + private static string? InternalFormat(RuntimeType enumType, ulong value) { EnumInfo enumInfo = GetEnumInfo(enumType); @@ -163,12 +163,12 @@ namespace System } } - private static string InternalFlagsFormat(RuntimeType enumType, ulong result) + private static string? InternalFlagsFormat(RuntimeType enumType, ulong result) { return InternalFlagsFormat(enumType, GetEnumInfo(enumType), result); } - private static string InternalFlagsFormat(RuntimeType enumType, EnumInfo enumInfo, ulong resultValue) + private static string? InternalFlagsFormat(RuntimeType enumType, EnumInfo enumInfo, ulong resultValue) { Debug.Assert(enumType != null); @@ -322,9 +322,9 @@ namespace System public static object Parse(Type enumType, string value, bool ignoreCase) { - bool success = TryParse(enumType, value, ignoreCase, throwOnFailure: true, out object result); + bool success = TryParse(enumType, value, ignoreCase, throwOnFailure: true, out object? result); Debug.Assert(success); - return result; + return result!; } public static TEnum Parse<TEnum>(string value) where TEnum : struct => @@ -337,13 +337,13 @@ namespace System return result; } - public static bool TryParse(Type enumType, string value, out object result) => + public static bool TryParse(Type enumType, string? value, out object? result) => TryParse(enumType, value, ignoreCase: false, out result); - public static bool TryParse(Type enumType, string value, bool ignoreCase, out object result) => + public static bool TryParse(Type enumType, string? value, bool ignoreCase, out object? result) => TryParse(enumType, value, ignoreCase, throwOnFailure: false, out result); - private static bool TryParse(Type enumType, string value, bool ignoreCase, bool throwOnFailure, out object result) + private static bool TryParse(Type enumType, string? value, bool ignoreCase, bool throwOnFailure, out object? result) { // Validation on the enum type itself. Failures here are considered non-parsing failures // and thus always throw rather than returning false. @@ -413,13 +413,13 @@ namespace System } } - public static bool TryParse<TEnum>(string value, out TEnum result) where TEnum : struct => + public static bool TryParse<TEnum>(string? value, out TEnum result) where TEnum : struct => TryParse<TEnum>(value, ignoreCase: false, out result); - public static bool TryParse<TEnum>(string value, bool ignoreCase, out TEnum result) where TEnum : struct => + public static bool TryParse<TEnum>(string? value, bool ignoreCase, out TEnum result) where TEnum : struct => TryParse<TEnum>(value, ignoreCase, throwOnFailure: false, out result); - private static bool TryParse<TEnum>(string value, bool ignoreCase, bool throwOnFailure, out TEnum result) where TEnum : struct + private static bool TryParse<TEnum>(string? value, bool ignoreCase, bool throwOnFailure, out TEnum result) where TEnum : struct { // Validation on the enum type itself. Failures here are considered non-parsing failures // and thus always throw rather than returning false. @@ -493,7 +493,7 @@ namespace System return parsed; default: - parsed = TryParseRareEnum(rt, value, valueSpan, ignoreCase, throwOnFailure, out object objectResult); + parsed = TryParseRareEnum(rt, value, valueSpan, ignoreCase, throwOnFailure, out object? objectResult); result = parsed ? (TEnum)objectResult : default; return parsed; } @@ -501,7 +501,7 @@ namespace System /// <summary>Tries to parse the value of an enum with known underlying types that fit in an Int32 (Int32, Int16, and SByte).</summary> private static bool TryParseInt32Enum( - RuntimeType enumType, string originalValueString, ReadOnlySpan<char> value, int minInclusive, int maxInclusive, bool ignoreCase, bool throwOnFailure, TypeCode type, out int result) + RuntimeType enumType, string? originalValueString, ReadOnlySpan<char> value, int minInclusive, int maxInclusive, bool ignoreCase, bool throwOnFailure, TypeCode type, out int result) { Debug.Assert( enumType.GetEnumUnderlyingType() == typeof(sbyte) || @@ -542,7 +542,7 @@ namespace System } /// <summary>Tries to parse the value of an enum with known underlying types that fit in a UInt32 (UInt32, UInt16, and Byte).</summary> - private static bool TryParseUInt32Enum(RuntimeType enumType, string originalValueString, ReadOnlySpan<char> value, uint maxInclusive, bool ignoreCase, bool throwOnFailure, TypeCode type, out uint result) + private static bool TryParseUInt32Enum(RuntimeType enumType, string? originalValueString, ReadOnlySpan<char> value, uint maxInclusive, bool ignoreCase, bool throwOnFailure, TypeCode type, out uint result) { Debug.Assert( enumType.GetEnumUnderlyingType() == typeof(byte) || @@ -583,7 +583,7 @@ namespace System } /// <summary>Tries to parse the value of an enum with Int64 as the underlying type.</summary> - private static bool TryParseInt64Enum(RuntimeType enumType, string originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out long result) + private static bool TryParseInt64Enum(RuntimeType enumType, string? originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out long result) { Debug.Assert(enumType.GetEnumUnderlyingType() == typeof(long)); @@ -615,7 +615,7 @@ namespace System } /// <summary>Tries to parse the value of an enum with UInt64 as the underlying type.</summary> - private static bool TryParseUInt64Enum(RuntimeType enumType, string originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out ulong result) + private static bool TryParseUInt64Enum(RuntimeType enumType, string? originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out ulong result) { Debug.Assert(enumType.GetEnumUnderlyingType() == typeof(ulong)); @@ -646,7 +646,7 @@ namespace System } /// <summary>Tries to parse the value of an enum with an underlying type that can't be expressed in C# (e.g. char, bool, double, etc.)</summary> - private static bool TryParseRareEnum(RuntimeType enumType, string originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out object result) + private static bool TryParseRareEnum(RuntimeType enumType, string? originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out object? result) { Debug.Assert( enumType.GetEnumUnderlyingType() != typeof(sbyte) && @@ -693,7 +693,7 @@ namespace System return false; } - private static bool TryParseByName(RuntimeType enumType, string originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out ulong result) + private static bool TryParseByName(RuntimeType enumType, string? originalValueString, ReadOnlySpan<char> value, bool ignoreCase, bool throwOnFailure, out ulong result) { // Find the field. Let's assume that these are always static classes because the class is an enum. EnumInfo enumInfo = GetEnumInfo(enumType); @@ -862,11 +862,11 @@ namespace System { case 'G': case 'g': - return GetEnumName(rtType, ToUInt64(value)) ?? value.ToString(); + return GetEnumName(rtType, ToUInt64(value)) ?? value.ToString()!; case 'D': case 'd': - return value.ToString(); + return value.ToString()!; case 'X': case 'x': @@ -874,7 +874,7 @@ namespace System case 'F': case 'f': - return InternalFlagsFormat(rtType, ToUInt64(value)) ?? value.ToString(); + return InternalFlagsFormat(rtType, ToUInt64(value)) ?? value.ToString()!; } } @@ -917,8 +917,7 @@ namespace System case CorElementType.ELEMENT_TYPE_U: return Unsafe.As<byte, UIntPtr>(ref data); default: - Debug.Fail("Invalid primitive type"); - return null; + throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType); } } @@ -953,8 +952,7 @@ namespace System case CorElementType.ELEMENT_TYPE_U: return (ulong)Unsafe.As<byte, UIntPtr>(ref data); default: - Debug.Fail("Invalid primitive type"); - return 0; + throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType); } } @@ -999,8 +997,7 @@ namespace System case CorElementType.ELEMENT_TYPE_U: return Unsafe.As<byte, UIntPtr>(ref data).GetHashCode(); default: - Debug.Fail("Invalid primitive type"); - return 0; + throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType); } } @@ -1019,14 +1016,14 @@ namespace System #region IFormattable [Obsolete("The provider argument is not used. Please use ToString(String).")] - public string ToString(string format, IFormatProvider provider) + public string ToString(string? format, IFormatProvider? provider) { return ToString(format); } #endregion #region Public Methods - public string ToString(string format) + public string ToString(string? format) { if (string.IsNullOrEmpty(format)) { @@ -1059,7 +1056,7 @@ namespace System } [Obsolete("The provider argument is not used. Please use ToString().")] - public string ToString(IFormatProvider provider) + public string ToString(IFormatProvider? provider) { return ToString(); } @@ -1096,77 +1093,77 @@ namespace System } } - bool IConvertible.ToBoolean(IFormatProvider provider) + bool IConvertible.ToBoolean(IFormatProvider? provider) { return Convert.ToBoolean(GetValue(), CultureInfo.CurrentCulture); } - char IConvertible.ToChar(IFormatProvider provider) + char IConvertible.ToChar(IFormatProvider? provider) { return Convert.ToChar(GetValue(), CultureInfo.CurrentCulture); } - sbyte IConvertible.ToSByte(IFormatProvider provider) + sbyte IConvertible.ToSByte(IFormatProvider? provider) { return Convert.ToSByte(GetValue(), CultureInfo.CurrentCulture); } - byte IConvertible.ToByte(IFormatProvider provider) + byte IConvertible.ToByte(IFormatProvider? provider) { return Convert.ToByte(GetValue(), CultureInfo.CurrentCulture); } - short IConvertible.ToInt16(IFormatProvider provider) + short IConvertible.ToInt16(IFormatProvider? provider) { return Convert.ToInt16(GetValue(), CultureInfo.CurrentCulture); } - ushort IConvertible.ToUInt16(IFormatProvider provider) + ushort IConvertible.ToUInt16(IFormatProvider? provider) { return Convert.ToUInt16(GetValue(), CultureInfo.CurrentCulture); } - int IConvertible.ToInt32(IFormatProvider provider) + int IConvertible.ToInt32(IFormatProvider? provider) { return Convert.ToInt32(GetValue(), CultureInfo.CurrentCulture); } - uint IConvertible.ToUInt32(IFormatProvider provider) + uint IConvertible.ToUInt32(IFormatProvider? provider) { return Convert.ToUInt32(GetValue(), CultureInfo.CurrentCulture); } - long IConvertible.ToInt64(IFormatProvider provider) + long IConvertible.ToInt64(IFormatProvider? provider) { return Convert.ToInt64(GetValue(), CultureInfo.CurrentCulture); } - ulong IConvertible.ToUInt64(IFormatProvider provider) + ulong IConvertible.ToUInt64(IFormatProvider? provider) { return Convert.ToUInt64(GetValue(), CultureInfo.CurrentCulture); } - float IConvertible.ToSingle(IFormatProvider provider) + float IConvertible.ToSingle(IFormatProvider? provider) { return Convert.ToSingle(GetValue(), CultureInfo.CurrentCulture); } - double IConvertible.ToDouble(IFormatProvider provider) + double IConvertible.ToDouble(IFormatProvider? provider) { return Convert.ToDouble(GetValue(), CultureInfo.CurrentCulture); } - decimal IConvertible.ToDecimal(IFormatProvider provider) + decimal IConvertible.ToDecimal(IFormatProvider? provider) { return Convert.ToDecimal(GetValue(), CultureInfo.CurrentCulture); } - DateTime IConvertible.ToDateTime(IFormatProvider provider) + DateTime IConvertible.ToDateTime(IFormatProvider? provider) { throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Enum", "DateTime")); } - object IConvertible.ToType(Type type, IFormatProvider provider) + object IConvertible.ToType(Type type, IFormatProvider? provider) { return Convert.DefaultToType((IConvertible)this, type, provider); } diff --git a/src/System.Private.CoreLib/shared/System/Exception.cs b/src/System.Private.CoreLib/shared/System/Exception.cs index 764f36a2fc..c2522d558b 100644 --- a/src/System.Private.CoreLib/shared/System/Exception.cs +++ b/src/System.Private.CoreLib/shared/System/Exception.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections; using System.Runtime.Serialization; @@ -16,7 +17,7 @@ namespace System _HResult = HResults.COR_E_EXCEPTION; } - public Exception(string message) + public Exception(string? message) : this() { _message = message; @@ -27,7 +28,7 @@ namespace System // Note: the stack trace is not started until the exception // is thrown // - public Exception(string message, Exception innerException) + public Exception(string? message, Exception? innerException) : this() { _message = message; @@ -72,7 +73,7 @@ namespace System // This will traverse exceptions using the innerException property. public virtual Exception GetBaseException() { - Exception inner = InnerException; + Exception? inner = InnerException; Exception back = this; while (inner != null) @@ -84,12 +85,12 @@ namespace System return back; } - public Exception InnerException => _innerException; + public Exception? InnerException => _innerException; // Sets the help link for this exception. // This should be in a URL/URN form, such as: // "file:///C:/Applications/Bazzal/help.html#ErrorNum42" - public virtual string HelpLink + public virtual string? HelpLink { get { @@ -101,7 +102,7 @@ namespace System } } - public virtual string Source + public virtual string? Source { get { @@ -148,7 +149,7 @@ namespace System { string s = GetClassName(); - string message = (needMessage ? Message : null); + string? message = (needMessage ? Message : null); if (!string.IsNullOrEmpty(message)) { s += ": " + message; @@ -160,7 +161,7 @@ namespace System " " + SR.Exception_EndOfInnerExceptionStack; } - string stackTrace = GetStackTrace(needFileLineInfo); + string? stackTrace = GetStackTrace(needFileLineInfo); if (stackTrace != null) { s += Environment.NewLine + stackTrace; diff --git a/src/System.Private.CoreLib/shared/System/ExecutionEngineException.cs b/src/System.Private.CoreLib/shared/System/ExecutionEngineException.cs index 5649cc082b..3097988890 100644 --- a/src/System.Private.CoreLib/shared/System/ExecutionEngineException.cs +++ b/src/System.Private.CoreLib/shared/System/ExecutionEngineException.cs @@ -15,6 +15,7 @@ ** =============================================================================*/ +#nullable enable using System; using System.Runtime.Serialization; @@ -31,13 +32,13 @@ namespace System HResult = HResults.COR_E_EXECUTIONENGINE; } - public ExecutionEngineException(string message) + public ExecutionEngineException(string? message) : base(message) { HResult = HResults.COR_E_EXECUTIONENGINE; } - public ExecutionEngineException(string message, Exception innerException) + public ExecutionEngineException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_EXECUTIONENGINE; diff --git a/src/System.Private.CoreLib/shared/System/FieldAccessException.cs b/src/System.Private.CoreLib/shared/System/FieldAccessException.cs index b23984133c..c0b2bd6630 100644 --- a/src/System.Private.CoreLib/shared/System/FieldAccessException.cs +++ b/src/System.Private.CoreLib/shared/System/FieldAccessException.cs @@ -9,6 +9,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -23,13 +24,13 @@ namespace System HResult = HResults.COR_E_FIELDACCESS; } - public FieldAccessException(string message) + public FieldAccessException(string? message) : base(message) { HResult = HResults.COR_E_FIELDACCESS; } - public FieldAccessException(string message, Exception inner) + public FieldAccessException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_FIELDACCESS; diff --git a/src/System.Private.CoreLib/shared/System/FormatException.cs b/src/System.Private.CoreLib/shared/System/FormatException.cs index 97d5001f3f..9fefdca15e 100644 --- a/src/System.Private.CoreLib/shared/System/FormatException.cs +++ b/src/System.Private.CoreLib/shared/System/FormatException.cs @@ -11,6 +11,7 @@ ** ===========================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -25,13 +26,13 @@ namespace System HResult = HResults.COR_E_FORMAT; } - public FormatException(string message) + public FormatException(string? message) : base(message) { HResult = HResults.COR_E_FORMAT; } - public FormatException(string message, Exception innerException) + public FormatException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_FORMAT; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/Calendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/Calendar.cs index c54e558222..aa9a07111d 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/Calendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/Calendar.cs @@ -148,8 +148,8 @@ namespace System.Globalization { // From ECMA CLI spec, Partition III, section 3.27: // - // If overflow occurs converting a floating-point type to an integer, or if the floating-point value - // being converted to an integer is a NaN, the value returned is unspecified. + // If overflow occurs converting a floating-point type to an integer, or if the floating-point value + // being converted to an integer is a NaN, the value returned is unspecified. // // Based upon this, this method should be performing the comparison against the double // before attempting a cast. Otherwise, the result is undefined. @@ -323,7 +323,7 @@ namespace System.Globalization /// Get the list of era values. /// </summary> /// <returns>The int array of the era names supported in this calendar or null if era is not used.</returns> - public abstract int[]? Eras { get; } + public abstract int[] Eras { get; } // Returns the hour part of the specified DateTime. The returned value is an // integer between 0 and 23. @@ -418,7 +418,7 @@ namespace System.Globalization int day; int dayOfYear = GetDayOfYear(time) - 1; // Make the day of year to be 0-based, so that 1/1 is day 0. - + // Calculate the number of days between the first day of year (1/1) and the first day of the week. // This value will be a positive value from 0 ~ 6. We call this value as "offset". // @@ -465,7 +465,7 @@ namespace System.Globalization // Otherwise, the specified time falls on the week of previous year. // Call this method again by passing the last day of previous year. // the last day of the previous year may "underflow" to no longer be a valid date time for - // this calendar if we just subtract so we need the subclass to provide us with + // this calendar if we just subtract so we need the subclass to provide us with // that information if (time <= MinSupportedDateTime.AddDays(dayOfYear)) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs index 31217020bc..e57e0c5687 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Security; @@ -35,22 +36,25 @@ namespace System.Globalization private bool LoadCalendarDataFromSystem(string localeName, CalendarId calendarId) { bool result = true; - result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.NativeName, out this.sNativeName); - result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.MonthDay, out this.sMonthDay); + // TODO-NULLABLE: these can return null but are later replaced with String.Empty or other non-nullable value + result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.NativeName, out this.sNativeName!); + result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.MonthDay, out this.sMonthDay!); this.sMonthDay = NormalizeDatePattern(this.sMonthDay); - result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.ShortDates, out this.saShortDates); - result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.LongDates, out this.saLongDates); - result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.YearMonths, out this.saYearMonths); - result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.DayNames, out this.saDayNames); - result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.AbbrevDayNames, out this.saAbbrevDayNames); - result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.SuperShortDayNames, out this.saSuperShortDayNames); + result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.ShortDates, out this.saShortDates!); + result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.LongDates, out this.saLongDates!); + result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.YearMonths, out this.saYearMonths!); + result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.DayNames, out this.saDayNames!); + result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.AbbrevDayNames, out this.saAbbrevDayNames!); + result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.SuperShortDayNames, out this.saSuperShortDayNames!); - string leapHebrewMonthName = null; - result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthNames, out this.saMonthNames, ref leapHebrewMonthName); + string? leapHebrewMonthName = null; + result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthNames, out this.saMonthNames!, ref leapHebrewMonthName); if (leapHebrewMonthName != null) - { - // In Hebrew calendar, get the leap month name Adar II and override the non-leap month 7 + { + Debug.Assert(this.saMonthNames != null); + + // In Hebrew calendar, get the leap month name Adar II and override the non-leap month 7 Debug.Assert(calendarId == CalendarId.HEBREW && saMonthNames.Length == 13); saLeapYearMonthNames = (string[]) saMonthNames.Clone(); saLeapYearMonthNames[6] = leapHebrewMonthName; @@ -62,12 +66,12 @@ namespace System.Globalization saMonthNames[6] = leapHebrewMonthName; } - result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthNames, out this.saAbbrevMonthNames, ref leapHebrewMonthName); - result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthGenitiveNames, out this.saMonthGenitiveNames, ref leapHebrewMonthName); - result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthGenitiveNames, out this.saAbbrevMonthGenitiveNames, ref leapHebrewMonthName); + result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthNames, out this.saAbbrevMonthNames!, ref leapHebrewMonthName); + result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthGenitiveNames, out this.saMonthGenitiveNames!, ref leapHebrewMonthName); + result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthGenitiveNames, out this.saAbbrevMonthGenitiveNames!, ref leapHebrewMonthName); - result &= EnumEraNames(localeName, calendarId, CalendarDataType.EraNames, out this.saEraNames); - result &= EnumEraNames(localeName, calendarId, CalendarDataType.AbbrevEraNames, out this.saAbbrevEraNames); + result &= EnumEraNames(localeName, calendarId, CalendarDataType.EraNames, out this.saEraNames!); + result &= EnumEraNames(localeName, calendarId, CalendarDataType.AbbrevEraNames, out this.saAbbrevEraNames!); return result; } @@ -122,7 +126,7 @@ namespace System.Globalization out calendarString); } - private static bool EnumDatePatterns(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] datePatterns) + private static bool EnumDatePatterns(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? datePatterns) { datePatterns = null; @@ -171,14 +175,14 @@ namespace System.Globalization { if (s[index] == '\'') { - do + do { modifiedPattern[index] = s[index]; index++; } while (index < s.Length && s[index] != '\''); if (index >= s.Length) - return; + return; } else if (s[index] == 'y') { @@ -347,7 +351,7 @@ namespace System.Globalization return index - startIndex; } - private static bool EnumMonthNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] monthNames, ref string leapHebrewMonthName) + private static bool EnumMonthNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? monthNames, ref string? leapHebrewMonthName) { monthNames = null; @@ -366,13 +370,13 @@ namespace System.Globalization if (callbackContext.Results.Count > 13) { Debug.Assert(calendarId == CalendarId.HEBREW && callbackContext.Results.Count == 14); - + if (calendarId == CalendarId.HEBREW) { leapHebrewMonthName = callbackContext.Results[13]; } callbackContext.Results.RemoveRange(13, callbackContext.Results.Count - 13); - } + } monthNames = callbackContext.Results.ToArray(); } @@ -380,22 +384,22 @@ namespace System.Globalization return result; } - private static bool EnumEraNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] eraNames) + private static bool EnumEraNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? eraNames) { bool result = EnumCalendarInfo(localeName, calendarId, dataType, out eraNames); // .NET expects that only the Japanese calendars have more than 1 era. // So for other calendars, only return the latest era. - if (calendarId != CalendarId.JAPAN && calendarId != CalendarId.JAPANESELUNISOLAR && eraNames.Length > 0) + if (calendarId != CalendarId.JAPAN && calendarId != CalendarId.JAPANESELUNISOLAR && eraNames?.Length > 0) { - string[] latestEraName = new string[] { eraNames[eraNames.Length - 1] }; + string[] latestEraName = new string[] { eraNames![eraNames.Length - 1] }; eraNames = latestEraName; } return result; } - internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] calendarData) + internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[]? calendarData) { calendarData = null; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.cs b/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.cs index 56ddf75791..131dd6b315 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Globalization @@ -12,33 +13,37 @@ namespace System.Globalization // // NOTE: Calendars depend on the locale name that creates it. Only a few // properties are available without locales using CalendarData.GetCalendar(CalendarData) - + // + // TODO-NULLABLE: this class requires refactoring for proper annotations + // currently from user of this class all fields are non-nullable. + // To avoid potential breaking changes lots of workaround have + // been used to suppress errors internal partial class CalendarData { // Max calendars internal const int MAX_CALENDARS = 23; // Identity - internal string sNativeName; // Calendar Name for the locale + internal string sNativeName = null!; // Calendar Name for the locale // Formats - internal string[] saShortDates; // Short Data format, default first - internal string[] saYearMonths; // Year/Month Data format, default first - internal string[] saLongDates; // Long Data format, default first - internal string sMonthDay; // Month/Day format + internal string[] saShortDates = null!; // Short Data format, default first + internal string[] saYearMonths = null!; // Year/Month Data format, default first + internal string[] saLongDates = null!; // Long Data format, default first + internal string sMonthDay = null!; // Month/Day format // Calendar Parts Names - internal string[] saEraNames; // Names of Eras - internal string[] saAbbrevEraNames; // Abbreviated Era Names - internal string[] saAbbrevEnglishEraNames; // Abbreviated Era Names in English - internal string[] saDayNames; // Day Names, null to use locale data, starts on Sunday - internal string[] saAbbrevDayNames; // Abbrev Day Names, null to use locale data, starts on Sunday - internal string[] saSuperShortDayNames; // Super short Day of week names - internal string[] saMonthNames; // Month Names (13) - internal string[] saAbbrevMonthNames; // Abbrev Month Names (13) - internal string[] saMonthGenitiveNames; // Genitive Month Names (13) - internal string[] saAbbrevMonthGenitiveNames; // Genitive Abbrev Month Names (13) - internal string[] saLeapYearMonthNames; // Multiple strings for the month names in a leap year. + internal string[] saEraNames = null!; // Names of Eras + internal string[] saAbbrevEraNames = null!; // Abbreviated Era Names + internal string[] saAbbrevEnglishEraNames = null!; // Abbreviated Era Names in English + internal string[] saDayNames = null!; // Day Names, null to use locale data, starts on Sunday + internal string[] saAbbrevDayNames = null!; // Abbrev Day Names, null to use locale data, starts on Sunday + internal string[] saSuperShortDayNames = null!; // Super short Day of week names + internal string[] saMonthNames = null!; // Month Names (13) + internal string[] saAbbrevMonthNames = null!; // Abbrev Month Names (13) + internal string[] saMonthGenitiveNames = null!; // Genitive Month Names (13) + internal string[] saAbbrevMonthGenitiveNames = null!; // Genitive Abbrev Month Names (13) + internal string[] saLeapYearMonthNames = null!; // Multiple strings for the month names in a leap year. // Integers at end to make marshaller happier internal int iTwoDigitYearMax = 2029; // Max 2 digit year (for Y2K bug data entry) @@ -51,7 +56,9 @@ namespace System.Globalization internal static readonly CalendarData Invariant = CreateInvariant(); // Private constructor - private CalendarData() { } + private CalendarData() + { + } // Invariant factory private static CalendarData CreateInvariant() @@ -165,7 +172,7 @@ namespace System.Globalization this.saAbbrevEnglishEraNames = new string[] { "" }; } - // Japanese is the only thing with > 1 era. Its current era # is how many ever + // Japanese is the only thing with > 1 era. Its current era # is how many ever // eras are in the array. (And the others all have 1 string in the array) this.iCurrentEra = this.saEraNames.Length; } @@ -177,7 +184,7 @@ namespace System.Globalization { // For Localized Gregorian we really expect the data from the OS. case CalendarId.GREGORIAN: - // Fallback for CoreCLR < Win7 or culture.dll missing + // Fallback for CoreCLR < Win7 or culture.dll missing if (this.saEraNames == null || this.saEraNames.Length == 0 || string.IsNullOrEmpty(this.saEraNames[0])) { this.saEraNames = new string[] { "A.D." }; @@ -260,7 +267,7 @@ namespace System.Globalization { // For Localized Gregorian we really expect the data from the OS. case CalendarId.GREGORIAN: - // Fallback for CoreCLR < Win7 or culture.dll missing + // Fallback for CoreCLR < Win7 or culture.dll missing if (this.saAbbrevEraNames == null || this.saAbbrevEraNames.Length == 0 || string.IsNullOrEmpty(this.saAbbrevEraNames[0])) { this.saAbbrevEraNames = new string[] { "AD" }; @@ -320,7 +327,7 @@ namespace System.Globalization // // Get a calendar. // Unfortunately we depend on the locale in the OS, so we need a locale - // no matter what. So just get the appropriate calendar from the + // no matter what. So just get the appropriate calendar from the // appropriate locale here // @@ -375,4 +382,3 @@ namespace System.Globalization } } } - diff --git a/src/System.Private.CoreLib/shared/System/Globalization/ChineseLunisolarCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/ChineseLunisolarCalendar.cs index ef68ce21b7..c7c129f338 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/ChineseLunisolarCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/ChineseLunisolarCalendar.cs @@ -308,6 +308,6 @@ namespace System.Globalization } } - public override int[]? Eras => new int[] { ChineseEra }; + public override int[] Eras => new int[] { ChineseEra }; } } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.Invariant.cs b/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.Invariant.cs index 16201b8d1f..d579dbefcb 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.Invariant.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.Invariant.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.Unix.cs index be33668d44..bbb07a7535 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -15,7 +16,7 @@ namespace System.Globalization public partial class CompareInfo { [NonSerialized] - private Interop.Globalization.SafeSortHandle _sortHandle; + private Interop.Globalization.SafeSortHandle _sortHandle = null!; // initialized in helper called by ctors [NonSerialized] private bool _isAsciiEqualityOrdinal; @@ -164,8 +165,8 @@ namespace System.Globalization return -1; } - // startIndex is the index into source where we start search backwards from. - // leftStartIndex is the index into source of the start of the string that is + // startIndex is the index into source where we start search backwards from. + // leftStartIndex is the index into source of the start of the string that is // count characters away from startIndex. int leftStartIndex = startIndex - count + 1; @@ -581,7 +582,7 @@ namespace System.Globalization // uppercase both chars - notice that we need just one compare per char if ((uint)(charA - 'a') <= (uint)('z' - 'a')) charA -= 0x20; if ((uint)(charB - 'a') <= (uint)('z' - 'a')) charB -= 0x20; - + if (charA != charB) return false; @@ -616,7 +617,7 @@ namespace System.Globalization { int charA = *a; int charB = *b; - + if (charA != charB) return false; @@ -714,7 +715,7 @@ namespace System.Globalization // uppercase both chars - notice that we need just one compare per char if ((uint)(charA - 'a') <= (uint)('z' - 'a')) charA -= 0x20; if ((uint)(charB - 'a') <= (uint)('z' - 'a')) charB -= 0x20; - + if (charA != charB) return false; @@ -749,7 +750,7 @@ namespace System.Globalization { int charA = *a; int charB = *b; - + if (charA != charB) return false; @@ -773,10 +774,10 @@ namespace System.Globalization { throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options)); } - + byte [] keyData; if (source.Length == 0) - { + { keyData = Array.Empty<Byte>(); } else @@ -797,7 +798,7 @@ namespace System.Globalization } return new SortKey(Name, source, options, keyData); - } + } private static unsafe bool IsSortable(char *text, int length) { @@ -856,7 +857,7 @@ namespace System.Globalization { int sortKeyLength = Interop.Globalization.GetSortKey(_sortHandle, pSource, source.Length, null, 0, options); - byte[] borrowedArr = null; + byte[]? borrowedArr = null; Span<byte> span = sortKeyLength <= 512 ? stackalloc byte[512] : (borrowedArr = ArrayPool<byte>.Shared.Rent(sortKeyLength)); @@ -912,7 +913,7 @@ namespace System.Globalization return buffer; } - + private SortVersion GetSortVersion() { Debug.Assert(!GlobalizationMode.Invariant); diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.Windows.cs b/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.Windows.cs index 749e2ad654..b706ad50e1 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers; using System.Diagnostics; using System.Runtime.InteropServices; @@ -111,7 +112,7 @@ namespace System.Globalization return FindStringOrdinal(FIND_FROMEND, source, startIndex - count + 1, count, value, value.Length, ignoreCase); } - + private unsafe int GetHashCodeOfStringCore(ReadOnlySpan<char> source, CompareOptions options) { Debug.Assert(!GlobalizationMode.Invariant); @@ -141,7 +142,7 @@ namespace System.Globalization // sort keys, LCMapStringEx treats the output buffer as containing opaque binary data. // See https://docs.microsoft.com/en-us/windows/desktop/api/winnls/nf-winnls-lcmapstringex. - byte[] borrowedArr = null; + byte[]? borrowedArr = null; Span<byte> span = sortKeyLength <= 512 ? stackalloc byte[512] : (borrowedArr = ArrayPool<byte>.Shared.Rent(sortKeyLength)); @@ -177,7 +178,7 @@ namespace System.Globalization fixed (char* char1 = &string1) fixed (char* char2 = &string2) { - // Use the OS to compare and then convert the result to expected value by subtracting 2 + // Use the OS to compare and then convert the result to expected value by subtracting 2 return Interop.Kernel32.CompareStringOrdinal(char1, count1, char2, count2, true) - 2; } } @@ -191,7 +192,7 @@ namespace System.Globalization Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); - string localeName = _sortHandle != IntPtr.Zero ? null : _sortName; + string? localeName = _sortHandle != IntPtr.Zero ? null : _sortName; fixed (char* pLocaleName = localeName) fixed (char* pString1 = &MemoryMarshal.GetReference(string1)) @@ -224,7 +225,7 @@ namespace System.Globalization Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); - string localeName = _sortHandle != IntPtr.Zero ? null : _sortName; + string? localeName = _sortHandle != IntPtr.Zero ? null : _sortName; fixed (char* pLocaleName = localeName) fixed (char* pString1 = &MemoryMarshal.GetReference(string1)) @@ -263,7 +264,7 @@ namespace System.Globalization Debug.Assert(!lpStringSource.IsEmpty); Debug.Assert(!lpStringValue.IsEmpty); - string localeName = _sortHandle != IntPtr.Zero ? null : _sortName; + string? localeName = _sortHandle != IntPtr.Zero ? null : _sortName; fixed (char* pLocaleName = localeName) fixed (char* pSource = &MemoryMarshal.GetReference(lpStringSource)) @@ -282,7 +283,7 @@ namespace System.Globalization _sortHandle); } } - + private unsafe int FindString( uint dwFindNLSStringFlags, string lpStringSource, @@ -297,7 +298,7 @@ namespace System.Globalization Debug.Assert(lpStringSource != null); Debug.Assert(lpStringValue != null); - string localeName = _sortHandle != IntPtr.Zero ? null : _sortName; + string? localeName = _sortHandle != IntPtr.Zero ? null : _sortName; fixed (char* pLocaleName = localeName) fixed (char* pSource = lpStringSource) @@ -493,9 +494,9 @@ namespace System.Globalization throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options)); } - byte [] keyData = null; + byte [] keyData; if (source.Length == 0) - { + { keyData = Array.Empty<byte>(); } else diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.cs index 97bb90f977..f5bba908b5 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; @@ -50,10 +51,10 @@ namespace System.Globalization private string m_name; // The name used to construct this CompareInfo. Do not rename (binary serialization) [NonSerialized] - private string _sortName; // The name that defines our behavior + private string _sortName = null!; // The name that defines our behavior [OptionalField(VersionAdded = 3)] - private SortVersion m_SortVersion; // Do not rename (binary serialization) + private SortVersion? m_SortVersion; // Do not rename (binary serialization) private int culture; // Do not rename (binary serialization). The fields sole purpose is to support Desktop serialization. @@ -170,7 +171,9 @@ namespace System.Globalization [OnDeserializing] private void OnDeserializing(StreamingContext ctx) { - m_name = null; + // TODO-NULLABLE: this becomes null for a brief moment before deserialization + // after serialization is finished it is never null + m_name = null!; } void IDeserializationCallback.OnDeserialization(object sender) @@ -216,7 +219,6 @@ namespace System.Globalization /// and the locale's changed behavior, then you'll get changed behavior, which is like /// what happens for a version update) /// </summary> - public virtual string Name { get @@ -237,12 +239,12 @@ namespace System.Globalization /// than string2, and a number greater than 0 if string1 is greater /// than string2. /// </summary> - public virtual int Compare(string string1, string string2) + public virtual int Compare(string? string1, string? string2) { return Compare(string1, string2, CompareOptions.None); } - public virtual int Compare(string string1, string string2, CompareOptions options) + public virtual int Compare(string? string1, string? string2, CompareOptions options) { if (options == CompareOptions.OrdinalIgnoreCase) { @@ -296,7 +298,7 @@ namespace System.Globalization // TODO https://github.com/dotnet/coreclr/issues/13827: // This method shouldn't be necessary, as we should be able to just use the overload // that takes two spans. But due to this issue, that's adding significant overhead. - internal int Compare(ReadOnlySpan<char> string1, string string2, CompareOptions options) + internal int Compare(ReadOnlySpan<char> string1, string? string2, CompareOptions options) { if (options == CompareOptions.OrdinalIgnoreCase) { @@ -368,23 +370,23 @@ namespace System.Globalization /// string1 is less than string2, and a number greater than 0 if /// string1 is greater than string2. /// </summary> - public virtual int Compare(string string1, int offset1, int length1, string string2, int offset2, int length2) + public virtual int Compare(string? string1, int offset1, int length1, string? string2, int offset2, int length2) { return Compare(string1, offset1, length1, string2, offset2, length2, 0); } - public virtual int Compare(string string1, int offset1, string string2, int offset2, CompareOptions options) + public virtual int Compare(string? string1, int offset1, string? string2, int offset2, CompareOptions options) { return Compare(string1, offset1, string1 == null ? 0 : string1.Length - offset1, string2, offset2, string2 == null ? 0 : string2.Length - offset2, options); } - public virtual int Compare(string string1, int offset1, string string2, int offset2) + public virtual int Compare(string? string1, int offset1, string? string2, int offset2) { return Compare(string1, offset1, string2, offset2, 0); } - public virtual int Compare(string string1, int offset1, int length1, string string2, int offset2, int length2, CompareOptions options) + public virtual int Compare(string? string1, int offset1, int length1, string? string2, int offset2, int length2, CompareOptions options) { if (options == CompareOptions.OrdinalIgnoreCase) { @@ -499,7 +501,7 @@ namespace System.Globalization while (length != 0 && charA <= maxChar && charB <= maxChar) { - // Ordinal equals or lowercase equals if the result ends up in the a-z range + // Ordinal equals or lowercase equals if the result ends up in the a-z range if (charA == charB || ((charA | 0x20) == (charB | 0x20) && (uint)((charA | 0x20) - 'a') <= (uint)('z' - 'a'))) @@ -659,7 +661,7 @@ namespace System.Globalization IntPtr byteOffset = IntPtr.Zero; while (length != 0) { - // Ordinal equals or lowercase equals if the result ends up in the a-z range + // Ordinal equals or lowercase equals if the result ends up in the a-z range uint valueA = Unsafe.AddByteOffset(ref charA, byteOffset); uint valueB = Unsafe.AddByteOffset(ref charB, byteOffset); @@ -1339,7 +1341,7 @@ namespace System.Globalization return CreateSortKey(source, CompareOptions.None); } - public override bool Equals(object value) + public override bool Equals(object? value) { return value is CompareInfo otherCompareInfo && Name == otherCompareInfo.Name; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Unix.cs index 57226ff752..f1a2669b97 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics; @@ -17,8 +18,7 @@ namespace System.Globalization const int ICU_ULOC_KEYWORD_AND_VALUES_CAPACITY = 100; // max size of keyword or value const int ICU_ULOC_FULLNAME_CAPACITY = 157; // max size of locale name const string ICU_COLLATION_KEYWORD = "@collation="; - - + /// <summary> /// This method uses the sRealName field (which is initialized by the constructor before this is called) to /// initialize the rest of the state of CultureData based on the underlying OS globalization library. @@ -58,6 +58,7 @@ namespace System.Globalization } // Replace the ICU collation keyword with an _ + Debug.Assert(_sWindowsName != null); index = _sWindowsName.IndexOf(ICU_COLLATION_KEYWORD, StringComparison.Ordinal); if (index >= 0) { @@ -76,9 +77,9 @@ namespace System.Globalization } _bNeutral = TwoLetterISOCountryName.Length == 0; - - _sSpecificCulture = _bNeutral ? LocaleData.GetSpecificCultureName(_sRealName) : _sRealName; - + + _sSpecificCulture = _bNeutral ? LocaleData.GetSpecificCultureName(_sRealName) : _sRealName; + // Remove the sort from sName unless custom culture if (index > 0 && !_bNeutral && !IsCustomCultureId(_iLanguage)) { @@ -87,7 +88,7 @@ namespace System.Globalization return true; } - internal static unsafe bool GetLocaleName(string localeName, out string windowsName) + internal static unsafe bool GetLocaleName(string localeName, out string? windowsName) { // Get the locale name from ICU char* buffer = stackalloc char[ICU_ULOC_FULLNAME_CAPACITY]; @@ -102,7 +103,7 @@ namespace System.Globalization return true; } - internal static unsafe bool GetDefaultLocaleName(out string windowsName) + internal static unsafe bool GetDefaultLocaleName(out string? windowsName) { // Get the default (system) locale name from ICU char* buffer = stackalloc char[ICU_ULOC_FULLNAME_CAPACITY]; @@ -116,11 +117,11 @@ namespace System.Globalization windowsName = new string(buffer); // the name passed to subsequent ICU calls return true; } - + private string GetLocaleInfo(LocaleStringData type) { Debug.Assert(!GlobalizationMode.Invariant); - + Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo] Expected _sWindowsName to be populated already"); return GetLocaleInfo(_sWindowsName, type); } @@ -163,7 +164,7 @@ namespace System.Globalization // returning 0 will cause the first supported calendar to be returned, which is the preferred calendar return 0; } - + int value = 0; bool result = Interop.Globalization.GetLocaleInfoInt(_sWindowsName, (uint)type, ref value); @@ -230,7 +231,7 @@ namespace System.Globalization return new string[] { format }; } - private static CultureData GetCultureDataFromRegionName(string regionName) + private static CultureData? GetCultureDataFromRegionName(string? regionName) { // no support to lookup by region name, other than the hard-coded list in CultureData return null; @@ -241,7 +242,7 @@ namespace System.Globalization return new CultureInfo(cultureName)._cultureData.GetLocaleInfo(cultureName, LocaleStringData.LocalizedDisplayName); } - private static string GetRegionDisplayName(string isoCountryCode) + private static string? GetRegionDisplayName(string? isoCountryCode) { // use the fallback which is to return NativeName return null; @@ -293,8 +294,8 @@ namespace System.Globalization return result.Slice(0, resultPos).ToString(); } - - private static string LCIDToLocaleName(int culture) + + private static string? LCIDToLocaleName(int culture) { Debug.Assert(!GlobalizationMode.Invariant); @@ -304,85 +305,84 @@ namespace System.Globalization private static int LocaleNameToLCID(string cultureName) { Debug.Assert(!GlobalizationMode.Invariant); - + int lcid = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.Lcid); - return lcid == -1 ? CultureInfo.LOCALE_CUSTOM_UNSPECIFIED : lcid; + return lcid == -1 ? CultureInfo.LOCALE_CUSTOM_UNSPECIFIED : lcid; } - + private static int GetAnsiCodePage(string cultureName) { int ansiCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.AnsiCodePage); - return ansiCodePage == -1 ? CultureData.Invariant.ANSICodePage : ansiCodePage; + return ansiCodePage == -1 ? CultureData.Invariant.ANSICodePage : ansiCodePage; } private static int GetOemCodePage(string cultureName) { int oemCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.OemCodePage); - return oemCodePage == -1 ? CultureData.Invariant.OEMCodePage : oemCodePage; + return oemCodePage == -1 ? CultureData.Invariant.OEMCodePage : oemCodePage; } private static int GetMacCodePage(string cultureName) { int macCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.MacCodePage); - return macCodePage == -1 ? CultureData.Invariant.MacCodePage : macCodePage; + return macCodePage == -1 ? CultureData.Invariant.MacCodePage : macCodePage; } private static int GetEbcdicCodePage(string cultureName) { int ebcdicCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.EbcdicCodePage); - return ebcdicCodePage == -1 ? CultureData.Invariant.EBCDICCodePage : ebcdicCodePage; + return ebcdicCodePage == -1 ? CultureData.Invariant.EBCDICCodePage : ebcdicCodePage; } private static int GetGeoId(string cultureName) { int geoId = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.GeoId); - return geoId == -1 ? CultureData.Invariant.GeoId : geoId; + return geoId == -1 ? CultureData.Invariant.GeoId : geoId; } - + private static int GetDigitSubstitution(string cultureName) { int digitSubstitution = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.DigitSubstitution); - return digitSubstitution == -1 ? (int) DigitShapes.None : digitSubstitution; + return digitSubstitution == -1 ? (int) DigitShapes.None : digitSubstitution; } private static string GetThreeLetterWindowsLanguageName(string cultureName) { - string langName = LocaleData.GetThreeLetterWindowsLanguageName(cultureName); - return langName == null ? "ZZZ" /* default lang name */ : langName; + return LocaleData.GetThreeLetterWindowsLanguageName(cultureName) ?? "ZZZ" /* default lang name */; } private static CultureInfo[] EnumCultures(CultureTypes types) { Debug.Assert(!GlobalizationMode.Invariant); - + if ((types & (CultureTypes.NeutralCultures | CultureTypes.SpecificCultures)) == 0) { return Array.Empty<CultureInfo>(); } - + int bufferLength = Interop.Globalization.GetLocales(null, 0); if (bufferLength <= 0) { return Array.Empty<CultureInfo>(); } - + char [] chars = new char[bufferLength]; - + bufferLength = Interop.Globalization.GetLocales(chars, bufferLength); if (bufferLength <= 0) { return Array.Empty<CultureInfo>(); } - - bool enumNeutrals = (types & CultureTypes.NeutralCultures) != 0; - bool enumSpecificss = (types & CultureTypes.SpecificCultures) != 0; - + + bool enumNeutrals = (types & CultureTypes.NeutralCultures) != 0; + bool enumSpecificss = (types & CultureTypes.SpecificCultures) != 0; + List<CultureInfo> list = new List<CultureInfo>(); - if (enumNeutrals) + if (enumNeutrals) { list.Add(CultureInfo.InvariantCulture); } - + int index = 0; while (index < bufferLength) { @@ -395,22 +395,22 @@ namespace System.Globalization list.Add(ci); } } - + index += length; } - + return list.ToArray(); } - + private static string GetConsoleFallbackName(string cultureName) { return LocaleData.GetConsoleUICulture(cultureName); } - + internal bool IsFramework => false; - + internal bool IsWin32Installed => false; - + internal bool IsReplacementCulture => false; } } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Windows.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Windows.cs index 151f771f93..f27b97e9a1 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -153,7 +154,7 @@ namespace System.Globalization // Wrappers around the GetLocaleInfoEx APIs which handle marshalling the returned // data as either and Int or string. - internal static unsafe string GetLocaleInfoEx(string localeName, uint field) + internal static unsafe string? GetLocaleInfoEx(string localeName, uint field) { // REVIEW: Determine the maximum size for the buffer const int BUFFER_SIZE = 530; @@ -211,16 +212,18 @@ namespace System.Globalization // Ask OS for data, note that we presume it returns success, so we have to know that // sWindowsName is valid before calling. Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already"); - return GetLocaleInfoExInt(_sWindowsName, lctype); + return GetLocaleInfoExInt(_sWindowsName, lctype); } private int[] GetLocaleInfo(LocaleGroupingData type) { + Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already"); return ConvertWin32GroupString(GetLocaleInfoFromLCType(_sWindowsName, (uint)type, UseUserOverride)); } - private string GetTimeFormatString() + private string? GetTimeFormatString() { + Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already"); return ReescapeWin32String(GetLocaleInfoFromLCType(_sWindowsName, Interop.Kernel32.LOCALE_STIMEFORMAT, UseUserOverride)); } @@ -234,27 +237,27 @@ namespace System.Globalization return ConvertFirstDayOfWeekMonToSun(result); } - private string[] GetTimeFormats() + private string[]? GetTimeFormats() { // Note that this gets overrides for us all the time Debug.Assert(_sWindowsName != null, "[CultureData.DoEnumTimeFormats] Expected _sWindowsName to be populated by already"); - string[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, 0, UseUserOverride)); + string[]? result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, 0, UseUserOverride)); return result; } - private string[] GetShortTimeFormats() + private string[]? GetShortTimeFormats() { // Note that this gets overrides for us all the time Debug.Assert(_sWindowsName != null, "[CultureData.DoEnumShortTimeFormats] Expected _sWindowsName to be populated by already"); - string[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, Interop.Kernel32.TIME_NOSECONDS, UseUserOverride)); + string[]? result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, Interop.Kernel32.TIME_NOSECONDS, UseUserOverride)); return result; } // Enumerate all system cultures and then try to find out which culture has // region name match the requested region name - private static CultureData GetCultureDataFromRegionName(string regionName) + private static CultureData? GetCultureDataFromRegionName(string regionName) { Debug.Assert(!GlobalizationMode.Invariant); Debug.Assert(regionName != null); @@ -284,7 +287,7 @@ namespace System.Globalization #else // Usually the UI culture shouldn't be different than what we got from WinRT except // if DefaultThreadCurrentUICulture was set - CultureInfo ci; + CultureInfo? ci; if (CultureInfo.DefaultThreadCurrentUICulture != null && ((ci = GetUserDefaultCulture()) != null) && @@ -337,14 +340,8 @@ namespace System.Globalization } // Ask OS for data - string result = GetLocaleInfoEx(localeName, lctype); - if (result == null) - { - // Failed, just use empty string - result = string.Empty; - } - - return result; + // Failed? Just use empty string + return GetLocaleInfoEx(localeName, lctype) ?? string.Empty; } /// <summary> @@ -360,7 +357,7 @@ namespace System.Globalization /// /// We don't build the stringbuilder unless we find something to change /// </summary> - internal static string ReescapeWin32String(string str) + internal static string? ReescapeWin32String(string? str) { // If we don't have data, then don't try anything if (str == null) @@ -368,7 +365,7 @@ namespace System.Globalization return null; } - StringBuilder result = null; + StringBuilder? result = null; bool inQuote = false; for (int i = 0; i < str.Length; i++) @@ -428,13 +425,14 @@ namespace System.Globalization return result.ToString(); } - internal static string[] ReescapeWin32Strings(string[] array) + internal static string[]? ReescapeWin32Strings(string[]? array) { if (array != null) { for (int i = 0; i < array.Length; i++) { - array[i] = ReescapeWin32String(array[i]); + // only returns null when null is passed + array[i] = ReescapeWin32String(array[i])!; } } @@ -503,7 +501,7 @@ namespace System.Globalization private struct EnumLocaleData { public string regionName; - public string cultureName; + public string? cultureName; } // EnumSystemLocaleEx callback. @@ -514,7 +512,7 @@ namespace System.Globalization try { string cultureName = new string(lpLocaleString); - string regionName = GetLocaleInfoEx(cultureName, Interop.Kernel32.LOCALE_SISO3166CTRYNAME); + string? regionName = GetLocaleInfoEx(cultureName, Interop.Kernel32.LOCALE_SISO3166CTRYNAME); if (regionName != null && regionName.Equals(context.regionName, StringComparison.OrdinalIgnoreCase)) { context.cultureName = cultureName; @@ -567,7 +565,7 @@ namespace System.Globalization } } - private static unsafe string[] nativeEnumTimeFormats(string localeName, uint dwFlags, bool useUserOverride) + private static unsafe string[]? nativeEnumTimeFormats(string localeName, uint dwFlags, bool useUserOverride) { EnumData data = new EnumData(); data.strings = new List<string>(); @@ -614,7 +612,7 @@ namespace System.Globalization return Interop.Kernel32.LocaleNameToLCID(cultureName, Interop.Kernel32.LOCALE_ALLOW_NEUTRAL_NAMES); } - private static unsafe string LCIDToLocaleName(int culture) + private static unsafe string? LCIDToLocaleName(int culture) { Debug.Assert(!GlobalizationMode.Invariant); diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.cs index 1280119912..7e1e66857f 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Text; @@ -55,87 +56,87 @@ namespace System.Globalization private const int undef = -1; // Override flag - private string _sRealName; // Name you passed in (ie: en-US, en, or de-DE_phoneb) - private string _sWindowsName; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in)) + private string _sRealName = null!; // Name you passed in (ie: en-US, en, or de-DE_phoneb). Initialized by helper called during initialization. + private string? _sWindowsName; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in)) // Identity - private string _sName; // locale name (ie: en-us, NO sort info, but could be neutral) - private string _sParent; // Parent name (which may be a custom locale/culture) - private string _sLocalizedDisplayName; // Localized pretty name for this locale - private string _sEnglishDisplayName; // English pretty name for this locale - private string _sNativeDisplayName; // Native pretty name for this locale - private string _sSpecificCulture; // The culture name to be used in CultureInfo.CreateSpecificCulture(), en-US form if neutral, sort name if sort + private string? _sName; // locale name (ie: en-us, NO sort info, but could be neutral) + private string? _sParent; // Parent name (which may be a custom locale/culture) + private string? _sLocalizedDisplayName; // Localized pretty name for this locale + private string? _sEnglishDisplayName; // English pretty name for this locale + private string? _sNativeDisplayName; // Native pretty name for this locale + private string? _sSpecificCulture; // The culture name to be used in CultureInfo.CreateSpecificCulture(), en-US form if neutral, sort name if sort // Language - private string _sISO639Language; // ISO 639 Language Name - private string _sISO639Language2; // ISO 639 Language Name - private string _sLocalizedLanguage; // Localized name for this language - private string _sEnglishLanguage; // English name for this language - private string _sNativeLanguage; // Native name of this language - private string _sAbbrevLang; // abbreviated language name (Windows Language Name) ex: ENU - private string _sConsoleFallbackName; // The culture name for the console fallback UI culture + private string? _sISO639Language; // ISO 639 Language Name + private string? _sISO639Language2; // ISO 639 Language Name + private string? _sLocalizedLanguage; // Localized name for this language + private string? _sEnglishLanguage; // English name for this language + private string? _sNativeLanguage; // Native name of this language + private string? _sAbbrevLang; // abbreviated language name (Windows Language Name) ex: ENU + private string? _sConsoleFallbackName; // The culture name for the console fallback UI culture private int _iInputLanguageHandle=undef;// input language handle // Region - private string _sRegionName; // (RegionInfo) - private string _sLocalizedCountry; // localized country name - private string _sEnglishCountry; // english country name (RegionInfo) - private string _sNativeCountry; // native country name - private string _sISO3166CountryName; // ISO 3166 (RegionInfo), ie: US - private string _sISO3166CountryName2; // 3 char ISO 3166 country name 2 2(RegionInfo) ex: USA (ISO) + private string? _sRegionName; // (RegionInfo) + private string? _sLocalizedCountry; // localized country name + private string? _sEnglishCountry; // english country name (RegionInfo) + private string? _sNativeCountry; // native country name + private string? _sISO3166CountryName; // ISO 3166 (RegionInfo), ie: US + private string? _sISO3166CountryName2; // 3 char ISO 3166 country name 2 2(RegionInfo) ex: USA (ISO) private int _iGeoId = undef; // GeoId // Numbers - private string _sPositiveSign; // (user can override) positive sign - private string _sNegativeSign; // (user can override) negative sign + private string? _sPositiveSign; // (user can override) positive sign + private string? _sNegativeSign; // (user can override) negative sign // (nfi populates these 5, don't have to be = undef) private int _iDigits; // (user can override) number of fractional digits private int _iNegativeNumber; // (user can override) negative number format - private int[] _waGrouping; // (user can override) grouping of digits - private string _sDecimalSeparator; // (user can override) decimal separator - private string _sThousandSeparator; // (user can override) thousands separator - private string _sNaN; // Not a Number - private string _sPositiveInfinity; // + Infinity - private string _sNegativeInfinity; // - Infinity + private int[]? _waGrouping; // (user can override) grouping of digits + private string? _sDecimalSeparator; // (user can override) decimal separator + private string? _sThousandSeparator; // (user can override) thousands separator + private string? _sNaN; // Not a Number + private string? _sPositiveInfinity; // + Infinity + private string? _sNegativeInfinity; // - Infinity // Percent private int _iNegativePercent = undef; // Negative Percent (0-3) private int _iPositivePercent = undef; // Positive Percent (0-11) - private string _sPercent; // Percent (%) symbol - private string _sPerMille; // PerMille symbol + private string? _sPercent; // Percent (%) symbol + private string? _sPerMille; // PerMille symbol // Currency - private string _sCurrency; // (user can override) local monetary symbol - private string _sIntlMonetarySymbol; // international monetary symbol (RegionInfo) - private string _sEnglishCurrency; // English name for this currency - private string _sNativeCurrency; // Native name for this currency + private string? _sCurrency; // (user can override) local monetary symbol + private string? _sIntlMonetarySymbol; // international monetary symbol (RegionInfo) + private string? _sEnglishCurrency; // English name for this currency + private string? _sNativeCurrency; // Native name for this currency // (nfi populates these 4, don't have to be = undef) private int _iCurrencyDigits; // (user can override) # local monetary fractional digits private int _iCurrency; // (user can override) positive currency format private int _iNegativeCurrency; // (user can override) negative currency format - private int[] _waMonetaryGrouping; // (user can override) monetary grouping of digits - private string _sMonetaryDecimal; // (user can override) monetary decimal separator - private string _sMonetaryThousand; // (user can override) monetary thousands separator + private int[]? _waMonetaryGrouping; // (user can override) monetary grouping of digits + private string? _sMonetaryDecimal; // (user can override) monetary decimal separator + private string? _sMonetaryThousand; // (user can override) monetary thousands separator // Misc private int _iMeasure = undef; // (user can override) system of measurement 0=metric, 1=US (RegionInfo) - private string _sListSeparator; // (user can override) list separator + private string? _sListSeparator; // (user can override) list separator // Time - private string _sAM1159; // (user can override) AM designator - private string _sPM2359; // (user can override) PM designator - private string _sTimeSeparator; - private volatile string[] _saLongTimes; // (user can override) time format - private volatile string[] _saShortTimes; // short time format - private volatile string[] _saDurationFormats; // time duration format + private string? _sAM1159; // (user can override) AM designator + private string? _sPM2359; // (user can override) PM designator + private string? _sTimeSeparator; + private volatile string[]? _saLongTimes; // (user can override) time format + private volatile string[]? _saShortTimes; // short time format + private volatile string[]? _saDurationFormats; // time duration format // Calendar specific data private int _iFirstDayOfWeek = undef; // (user can override) first day of week (gregorian really) private int _iFirstWeekOfYear = undef; // (user can override) first week of year (gregorian really) - private volatile CalendarId[] _waCalendars; // all available calendar type(s). The first one is the default calendar + private volatile CalendarId[]? _waCalendars; // all available calendar type(s). The first one is the default calendar // Store for specific data about each calendar - private CalendarData[] _calendars; // Store for specific calendar data + private CalendarData?[]? _calendars; // Store for specific calendar data // Text information private int _iReadingLayout = undef; // Reading layout data @@ -301,15 +302,15 @@ namespace System.Globalization s_regionNames = regionNames; } - return s_regionNames; + return s_regionNames!; } } // Cache of regions we've already looked up - private static volatile StringCultureDataDictionary s_cachedRegions; - private static volatile StringStringDictionary s_regionNames; + private static volatile StringCultureDataDictionary? s_cachedRegions; + private static volatile StringStringDictionary? s_regionNames; - internal static CultureData GetCultureDataForRegion(string cultureName, bool useUserOverride) + internal static CultureData? GetCultureDataForRegion(string? cultureName, bool useUserOverride) { // First do a shortcut for Invariant if (string.IsNullOrEmpty(cultureName)) @@ -318,7 +319,7 @@ namespace System.Globalization } // First check if GetCultureData() can find it (ie: its a real culture) - CultureData retVal = GetCultureData(cultureName, useUserOverride); + CultureData? retVal = GetCultureData(cultureName, useUserOverride); if (retVal != null && !retVal.IsNeutralCulture) { return retVal; @@ -328,11 +329,12 @@ namespace System.Globalization // (Remember this isn't a core clr path where that's not supported) // If it was neutral remember that so that RegionInfo() can throw the right exception - CultureData neutral = retVal; + CultureData? neutral = retVal; // Try the hash table next string hashName = AnsiToLower(useUserOverride ? cultureName : cultureName + '*'); - StringCultureDataDictionary tempHashTable = s_cachedRegions; + StringCultureDataDictionary? tempHashTable = s_cachedRegions; + if (tempHashTable == null) { // No table yet, make a new one @@ -562,13 +564,13 @@ namespace System.Globalization return s_Invariant; } } - private volatile static CultureData s_Invariant; + private volatile static CultureData? s_Invariant; // Cache of cultures we've already looked up - private static volatile StringCultureDataDictionary s_cachedCultures; + private static volatile StringCultureDataDictionary? s_cachedCultures; private static readonly object s_lock = new object(); - internal static CultureData GetCultureData(string cultureName, bool useUserOverride) + internal static CultureData? GetCultureData(string? cultureName, bool useUserOverride) { // First do a shortcut for Invariant if (string.IsNullOrEmpty(cultureName)) @@ -578,7 +580,7 @@ namespace System.Globalization // Try the hash table first string hashName = AnsiToLower(useUserOverride ? cultureName : cultureName + '*'); - StringCultureDataDictionary tempHashTable = s_cachedCultures; + StringCultureDataDictionary? tempHashTable = s_cachedCultures; if (tempHashTable == null) { // No table yet, make a new one @@ -600,7 +602,7 @@ namespace System.Globalization } // Not found in the hash table, need to see if we can build one that works for us - CultureData culture = CreateCultureData(cultureName, useUserOverride); + CultureData? culture = CreateCultureData(cultureName, useUserOverride); if (culture == null) { return null; @@ -677,7 +679,7 @@ namespace System.Globalization return name; } - private static CultureData CreateCultureData(string cultureName, bool useUserOverride) + private static CultureData? CreateCultureData(string cultureName, bool useUserOverride) { if (GlobalizationMode.Invariant) { @@ -711,7 +713,7 @@ namespace System.Globalization private bool InitCompatibilityCultureData() { // for compatibility handle the deprecated ids: zh-chs, zh-cht - string cultureName = _sRealName; + string cultureName = _sRealName!; string fallbackCultureName; string realCultureName; @@ -745,8 +747,8 @@ namespace System.Globalization /// We'd rather people use the named version since this doesn't allow custom locales internal static CultureData GetCultureData(int culture, bool bUseUserOverride) { - string localeName = null; - CultureData retVal = null; + string? localeName = null; + CultureData? retVal = null; if (culture == CultureInfo.LOCALE_INVARIANT) { @@ -794,9 +796,9 @@ namespace System.Globalization { case "zh-CHS": case "zh-CHT": - return _sName; + return _sName!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34273 } - return _sRealName; + return _sRealName!; } } @@ -818,7 +820,7 @@ namespace System.Globalization if (_sParent == null) { // Ask using the real name, so that we get parents of neutrals - _sParent = GetLocaleInfo(_sRealName, LocaleStringData.ParentName); + _sParent = GetLocaleInfo(_sRealName!, LocaleStringData.ParentName); } return _sParent; } @@ -935,7 +937,7 @@ namespace System.Globalization { // "Azeri (Latin)" + "Azerbaijan" -> "Azeri (Latin, Azerbaijan)" _sEnglishDisplayName = string.Concat( - EnglishLanguageName.AsSpan(0, _sEnglishLanguage.Length - 1), + EnglishLanguageName.AsSpan(0, _sEnglishLanguage!.Length - 1), ", ", EnglishCountryName, ")"); @@ -1044,7 +1046,7 @@ namespace System.Globalization { if (_sAbbrevLang == null) { - _sAbbrevLang = GetThreeLetterWindowsLanguageName(_sRealName); + _sAbbrevLang = GetThreeLetterWindowsLanguageName(_sRealName!); } return _sAbbrevLang; } @@ -1066,7 +1068,7 @@ namespace System.Globalization if (CultureInfo.DefaultThreadCurrentUICulture != null && ((ci = GetUserDefaultCulture()) != null) && - !CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name)) + !CultureInfo.DefaultThreadCurrentUICulture!.Name.Equals(ci.Name)) { _sLocalizedLanguage = NativeLanguageName; } @@ -1131,7 +1133,7 @@ namespace System.Globalization { if (_iGeoId == undef) { - _iGeoId = GetGeoId(_sRealName); + _iGeoId = GetGeoId(_sRealName!); } return _iGeoId; } @@ -1253,7 +1255,7 @@ namespace System.Globalization { if (_sConsoleFallbackName == null) { - _sConsoleFallbackName = GetConsoleFallbackName(_sRealName); + _sConsoleFallbackName = GetConsoleFallbackName(_sRealName!); } return _sConsoleFallbackName; } @@ -1528,10 +1530,10 @@ namespace System.Globalization { Debug.Assert(!GlobalizationMode.Invariant); - string[] longTimes = GetTimeFormats(); + string[]? longTimes = GetTimeFormats(); if (longTimes == null || longTimes.Length == 0) { - _saLongTimes = Invariant._saLongTimes; + _saLongTimes = Invariant._saLongTimes!; } else { @@ -1555,8 +1557,7 @@ namespace System.Globalization Debug.Assert(!GlobalizationMode.Invariant); // Try to get the short times from the OS/culture.dll - string[] shortTimes = null; - shortTimes = GetShortTimeFormats(); + string[]? shortTimes = GetShortTimeFormats(); if (shortTimes == null || shortTimes.Length == 0) { @@ -1830,7 +1831,7 @@ namespace System.Globalization if (count == 0) { // Failed for some reason, just grab Gregorian from Invariant - _waCalendars = Invariant._waCalendars; + _waCalendars = Invariant._waCalendars!; } else { @@ -1912,7 +1913,7 @@ namespace System.Globalization // we need the following local variable to avoid returning null // when another thread creates a new array of CalendarData (above) // right after we insert the newly created CalendarData (below) - CalendarData calendarData = _calendars[calendarIndex]; + CalendarData? calendarData = _calendars[calendarIndex]; // Make sure that calendar has data if (calendarData == null) { @@ -2002,7 +2003,7 @@ namespace System.Globalization { if (_iDefaultAnsiCodePage == undef) { - _iDefaultAnsiCodePage = GetAnsiCodePage(_sRealName); + _iDefaultAnsiCodePage = GetAnsiCodePage(_sRealName!); } return _iDefaultAnsiCodePage; } @@ -2017,7 +2018,7 @@ namespace System.Globalization { if (_iDefaultOemCodePage == undef) { - _iDefaultOemCodePage = GetOemCodePage(_sRealName); + _iDefaultOemCodePage = GetOemCodePage(_sRealName!); } return _iDefaultOemCodePage; } @@ -2032,7 +2033,7 @@ namespace System.Globalization { if (_iDefaultMacCodePage == undef) { - _iDefaultMacCodePage = GetMacCodePage(_sRealName); + _iDefaultMacCodePage = GetMacCodePage(_sRealName!); } return _iDefaultMacCodePage; } @@ -2047,7 +2048,7 @@ namespace System.Globalization { if (_iDefaultEbcdicCodePage == undef) { - _iDefaultEbcdicCodePage = GetEbcdicCodePage(_sRealName); + _iDefaultEbcdicCodePage = GetEbcdicCodePage(_sRealName!); } return _iDefaultEbcdicCodePage; } @@ -2136,7 +2137,7 @@ namespace System.Globalization { if (_sTimeSeparator == null) { - string longTimeFormat = GetTimeFormatString(); + string? longTimeFormat = GetTimeFormatString(); if (string.IsNullOrEmpty(longTimeFormat)) { longTimeFormat = LongTimes[0]; @@ -2190,7 +2191,7 @@ namespace System.Globalization Debug.Assert(str != null); Debug.Assert(start >= 0); Debug.Assert(end >= 0); - StringBuilder result = null; + StringBuilder? result = null; for (int i = start; i < str.Length && i <= end; i++) { @@ -2328,17 +2329,17 @@ namespace System.Globalization { if (GlobalizationMode.Invariant || IsInvariantCulture) { - nfi._positiveSign = _sPositiveSign; - nfi._negativeSign = _sNegativeSign; + nfi._positiveSign = _sPositiveSign!; + nfi._negativeSign = _sNegativeSign!; - nfi._numberGroupSeparator = _sThousandSeparator; - nfi._numberDecimalSeparator = _sDecimalSeparator; + nfi._numberGroupSeparator = _sThousandSeparator!; + nfi._numberDecimalSeparator = _sDecimalSeparator!; nfi._numberDecimalDigits = _iDigits; nfi._numberNegativePattern = _iNegativeNumber; - nfi._currencySymbol = _sCurrency; - nfi._currencyGroupSeparator = _sMonetaryThousand; - nfi._currencyDecimalSeparator = _sMonetaryDecimal; + nfi._currencySymbol = _sCurrency!; + nfi._currencyGroupSeparator = _sMonetaryThousand!; + nfi._currencyDecimalSeparator = _sMonetaryDecimal!; nfi._currencyDecimalDigits = _iCurrencyDigits; nfi._currencyNegativePattern = _iNegativeCurrency; nfi._currencyPositivePattern = _iCurrency; @@ -2371,6 +2372,7 @@ namespace System.Globalization nfi._nativeDigits[i] = char.ToString(digits[i]); } + Debug.Assert(_sRealName != null); nfi._digitSubstitution = GetDigitSubstitution(_sRealName); } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.Unix.cs index 0b897c878e..0973ee0876 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.Unix.cs @@ -2,6 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable +using System.Diagnostics; + namespace System.Globalization { public partial class CultureInfo : IFormatProvider @@ -11,10 +14,11 @@ namespace System.Globalization if (GlobalizationMode.Invariant) return CultureInfo.InvariantCulture; - CultureInfo cultureInfo = null; - string localeName; + CultureInfo cultureInfo; + string? localeName; if (CultureData.GetDefaultLocaleName(out localeName)) { + Debug.Assert(localeName != null); cultureInfo = GetCultureByName(localeName); } else diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.Windows.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.Windows.cs index c5479deac5..09041e9b7f 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable #if FEATURE_APPX using System.Resources; using Internal.Resources; @@ -24,7 +25,7 @@ namespace System.Globalization if (GlobalizationMode.Invariant) return CultureInfo.InvariantCulture; - string strDefault = CultureData.GetLocaleInfoEx(Interop.Kernel32.LOCALE_NAME_USER_DEFAULT, Interop.Kernel32.LOCALE_SNAME); + string? strDefault = CultureData.GetLocaleInfoEx(Interop.Kernel32.LOCALE_NAME_USER_DEFAULT, Interop.Kernel32.LOCALE_SNAME); if (strDefault == null) { strDefault = CultureData.GetLocaleInfoEx(Interop.Kernel32.LOCALE_NAME_SYSTEM_DEFAULT, Interop.Kernel32.LOCALE_SNAME); @@ -69,7 +70,7 @@ namespace System.Globalization } #if FEATURE_APPX - internal static CultureInfo GetCultureInfoForUserPreferredLanguageInAppX() + internal static CultureInfo? GetCultureInfoForUserPreferredLanguageInAppX() { // If a call to GetCultureInfoForUserPreferredLanguageInAppX() generated a recursive // call to itself, return null, since we don't want to stack overflow. For example, @@ -81,7 +82,7 @@ namespace System.Globalization return null; } - CultureInfo toReturn = null; + CultureInfo toReturn; try { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.cs index 1b22676bad..643327ce12 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.cs @@ -26,6 +26,7 @@ // //////////////////////////////////////////////////////////////////////////// +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Threading; @@ -59,11 +60,11 @@ namespace System.Globalization // We use the _cultureData to get the data for our object private bool _isReadOnly; - private CompareInfo _compareInfo; - private TextInfo _textInfo; - internal NumberFormatInfo _numInfo; - internal DateTimeFormatInfo _dateTimeInfo; - private Calendar _calendar; + private CompareInfo? _compareInfo; + private TextInfo? _textInfo; + internal NumberFormatInfo? _numInfo; + internal DateTimeFormatInfo? _dateTimeInfo; + private Calendar? _calendar; // // The CultureData instance that we are going to read data from. // For supported culture, this will be the CultureData instance that read data from mscorlib assembly. @@ -73,7 +74,7 @@ namespace System.Globalization internal bool _isInherited; - private CultureInfo _consoleFallbackCulture; + private CultureInfo? _consoleFallbackCulture; // Names are confusing. Here are 3 names we have: // @@ -91,18 +92,18 @@ namespace System.Globalization // This will hold the non sorting name to be returned from CultureInfo.Name property. // This has a de-DE style name even for de-DE_phoneb type cultures - private string _nonSortName; + private string? _nonSortName; // This will hold the sorting name to be returned from CultureInfo.SortName property. // This might be completely unrelated to the culture name if a custom culture. Ie en-US for fj-FJ. // Otherwise its the sort name, ie: de-DE or de-DE_phoneb - private string _sortName; + private string? _sortName; // Get the current user default culture. This one is almost always used, so we create it by default. - private static volatile CultureInfo s_userDefaultCulture; + private static volatile CultureInfo? s_userDefaultCulture; //The culture used in the user interface. This is mostly used to load correct localized resources. - private static volatile CultureInfo s_userDefaultUICulture; + private static volatile CultureInfo? s_userDefaultUICulture; // WARNING: We allow diagnostic tools to directly inspect these three members (s_InvariantCultureInfo, s_DefaultThreadCurrentUICulture and s_DefaultThreadCurrentCulture) // See https://github.com/dotnet/corert/blob/master/Documentation/design-docs/diagnostics/diagnostics-tools-contract.md for more details. @@ -113,16 +114,16 @@ namespace System.Globalization private static readonly CultureInfo s_InvariantCultureInfo = new CultureInfo(CultureData.Invariant, isReadOnly: true); // These are defaults that we use if a thread has not opted into having an explicit culture - private static volatile CultureInfo s_DefaultThreadCurrentUICulture; - private static volatile CultureInfo s_DefaultThreadCurrentCulture; + private static volatile CultureInfo? s_DefaultThreadCurrentUICulture; + private static volatile CultureInfo? s_DefaultThreadCurrentCulture; [ThreadStatic] private static CultureInfo s_currentThreadCulture; [ThreadStatic] private static CultureInfo s_currentThreadUICulture; - private static AsyncLocal<CultureInfo> s_asyncLocalCurrentCulture; - private static AsyncLocal<CultureInfo> s_asyncLocalCurrentUICulture; + private static AsyncLocal<CultureInfo>? s_asyncLocalCurrentCulture; + private static AsyncLocal<CultureInfo>? s_asyncLocalCurrentUICulture; private static void AsyncLocalSetCurrentCulture(AsyncLocalValueChangedArgs<CultureInfo> args) { @@ -135,11 +136,11 @@ namespace System.Globalization } private static readonly object _lock = new object(); - private static volatile Dictionary<string, CultureInfo> s_NameCachedCultures; - private static volatile Dictionary<int, CultureInfo> s_LcidCachedCultures; + private static volatile Dictionary<string, CultureInfo>? s_NameCachedCultures; + private static volatile Dictionary<int, CultureInfo>? s_LcidCachedCultures; // The parent culture. - private CultureInfo _parent; + private CultureInfo? _parent; // LOCALE constants of interest to us internally and privately for LCID functions // (ie: avoid using these and use names if possible) @@ -153,13 +154,13 @@ namespace System.Globalization private static CultureInfo InitializeUserDefaultCulture() { Interlocked.CompareExchange(ref s_userDefaultCulture, GetUserDefaultCulture(), null); - return s_userDefaultCulture; + return s_userDefaultCulture!; } private static CultureInfo InitializeUserDefaultUICulture() { Interlocked.CompareExchange(ref s_userDefaultUICulture, GetUserDefaultUICulture(), null); - return s_userDefaultUICulture; + return s_userDefaultUICulture!; } public CultureInfo(string name) : this(name, true) @@ -174,13 +175,14 @@ namespace System.Globalization } // Get our data providing record - _cultureData = CultureData.GetCultureData(name, useUserOverride); + CultureData? cultureData = CultureData.GetCultureData(name, useUserOverride); - if (_cultureData == null) + if (cultureData == null) { throw new CultureNotFoundException(nameof(name), name, SR.Argument_CultureNotSupported); } + _cultureData = cultureData; _name = _cultureData.CultureName; _isInherited = GetType() != typeof(CultureInfo); } @@ -194,10 +196,10 @@ namespace System.Globalization _isReadOnly = isReadOnly; } - private static CultureInfo CreateCultureInfoNoThrow(string name, bool useUserOverride) + private static CultureInfo? CreateCultureInfoNoThrow(string name, bool useUserOverride) { Debug.Assert(name != null); - CultureData cultureData = CultureData.GetCultureData(name, useUserOverride); + CultureData? cultureData = CultureData.GetCultureData(name, useUserOverride); if (cultureData == null) { return null; @@ -252,12 +254,14 @@ namespace System.Globalization throw new ArgumentNullException(nameof(cultureName), SR.ArgumentNull_String); } - _cultureData = CultureData.GetCultureData(cultureName, false); - if (_cultureData == null) + CultureData? cultureData = CultureData.GetCultureData(cultureName, false); + if (cultureData == null) { throw new CultureNotFoundException(nameof(cultureName), cultureName, SR.Argument_CultureNotSupported); } + _cultureData = cultureData; + _name = _cultureData.CultureName; CultureInfo altCulture = GetCultureInfo(textAndCompareCultureName); @@ -295,7 +299,7 @@ namespace System.Globalization /// </summary> public static CultureInfo CreateSpecificCulture(string name) { - CultureInfo culture; + CultureInfo? culture; try { @@ -403,24 +407,16 @@ namespace System.Globalization #if FEATURE_APPX if (ApplicationModel.IsUap) { - CultureInfo culture = GetCultureInfoForUserPreferredLanguageInAppX(); + CultureInfo? culture = GetCultureInfoForUserPreferredLanguageInAppX(); if (culture != null) return culture; } #endif - if (s_currentThreadCulture != null) - { - return s_currentThreadCulture; - } - - CultureInfo ci = s_DefaultThreadCurrentCulture; - if (ci != null) - { - return ci; - } - - return s_userDefaultCulture ?? InitializeUserDefaultCulture(); + return s_currentThreadCulture ?? + s_DefaultThreadCurrentCulture ?? + s_userDefaultCulture ?? + InitializeUserDefaultCulture(); } set { @@ -452,7 +448,7 @@ namespace System.Globalization { Interlocked.CompareExchange(ref s_asyncLocalCurrentCulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentCulture), null); } - s_asyncLocalCurrentCulture.Value = value; + s_asyncLocalCurrentCulture!.Value = value; } } @@ -470,24 +466,15 @@ namespace System.Globalization #if FEATURE_APPX if (ApplicationModel.IsUap) { - CultureInfo culture = GetCultureInfoForUserPreferredLanguageInAppX(); + CultureInfo? culture = GetCultureInfoForUserPreferredLanguageInAppX(); if (culture != null) return culture; } #endif - if (s_currentThreadUICulture != null) - { - return s_currentThreadUICulture; - } - - CultureInfo ci = s_DefaultThreadCurrentUICulture; - if (ci != null) - { - return ci; - } - - return UserDefaultUICulture; + return s_currentThreadUICulture ?? + s_DefaultThreadCurrentUICulture ?? + UserDefaultUICulture; } set { @@ -523,7 +510,7 @@ namespace System.Globalization } // this one will set s_currentThreadUICulture too - s_asyncLocalCurrentUICulture.Value = value; + s_asyncLocalCurrentUICulture!.Value = value; } } @@ -531,7 +518,7 @@ namespace System.Globalization public static CultureInfo InstalledUICulture => s_userDefaultCulture ?? InitializeUserDefaultCulture(); - public static CultureInfo DefaultThreadCurrentCulture + public static CultureInfo? DefaultThreadCurrentCulture { get => s_DefaultThreadCurrentCulture; set @@ -542,7 +529,7 @@ namespace System.Globalization } } - public static CultureInfo DefaultThreadCurrentUICulture + public static CultureInfo? DefaultThreadCurrentUICulture { get => s_DefaultThreadCurrentUICulture; set @@ -588,7 +575,7 @@ namespace System.Globalization { if (_parent == null) { - CultureInfo culture = null; + CultureInfo culture; string parentName = _cultureData.ParentName; if (string.IsNullOrEmpty(parentName)) @@ -597,19 +584,16 @@ namespace System.Globalization } else { - culture = CreateCultureInfoNoThrow(parentName, _cultureData.UseUserOverride); - if (culture == null) - { + culture = CreateCultureInfoNoThrow(parentName, _cultureData.UseUserOverride) ?? // For whatever reason our IPARENT or SPARENT wasn't correct, so use invariant // We can't allow ourselves to fail. In case of custom cultures the parent of the // current custom culture isn't installed. - culture = InvariantCulture; - } + InvariantCulture; } - Interlocked.CompareExchange<CultureInfo>(ref _parent, culture, null); + Interlocked.CompareExchange<CultureInfo?>(ref _parent, culture, null); } - return _parent; + return _parent!; } } @@ -760,7 +744,7 @@ namespace System.Globalization } } - public override bool Equals(object value) + public override bool Equals(object? value) { if (object.ReferenceEquals(this, value)) { @@ -789,7 +773,7 @@ namespace System.Globalization /// </summary> public override string ToString() => _name; - public virtual object GetFormat(Type formatType) + public virtual object? GetFormat(Type? formatType) { if (formatType == typeof(NumberFormatInfo)) { @@ -844,7 +828,7 @@ namespace System.Globalization temp._isReadOnly = _isReadOnly; Interlocked.CompareExchange(ref _numInfo, temp, null); } - return _numInfo; + return _numInfo!; } set { @@ -873,7 +857,7 @@ namespace System.Globalization temp._isReadOnly = _isReadOnly; Interlocked.CompareExchange(ref _dateTimeInfo, temp, null); } - return _dateTimeInfo; + return _dateTimeInfo!; } set @@ -1005,7 +989,7 @@ namespace System.Globalization public CultureInfo GetConsoleFallbackUICulture() { - CultureInfo temp = _consoleFallbackCulture; + CultureInfo? temp = _consoleFallbackCulture; if (temp == null) { temp = CreateSpecificCulture(_cultureData.SCONSOLEFALLBACKNAME); @@ -1129,13 +1113,13 @@ namespace System.Globalization /// Helper function overloads of GetCachedReadOnlyCulture. If lcid is 0, we use the name. /// If lcid is -1, use the altName and create one of those special SQL cultures. /// </summary> - internal static CultureInfo GetCultureInfoHelper(int lcid, string name, string altName) + internal static CultureInfo? GetCultureInfoHelper(int lcid, string? name, string? altName) { // retval is our return value. - CultureInfo retval; + CultureInfo? retval; // Temporary hashtable for the names. - Dictionary<string, CultureInfo> tempNameHT = s_NameCachedCultures; + Dictionary<string, CultureInfo>? tempNameHT = s_NameCachedCultures; if (name != null) { @@ -1157,10 +1141,11 @@ namespace System.Globalization // If we are called by name, check if the object exists in the hashtable. If so, return it. if (lcid == -1 || lcid == 0) { + Debug.Assert(name != null && (lcid != -1 || altName != null)); bool ret; lock (_lock) { - ret = tempNameHT.TryGetValue(lcid == 0 ? name : name + '\xfffd' + altName, out retval); + ret = tempNameHT.TryGetValue(lcid == 0 ? name! : name! + '\xfffd' + altName!, out retval); } if (ret && retval != null) @@ -1171,7 +1156,7 @@ namespace System.Globalization } // Next, the Lcid table. - Dictionary<int, CultureInfo> tempLcidHT = s_LcidCachedCultures; + Dictionary<int, CultureInfo>? tempLcidHT = s_LcidCachedCultures; if (tempLcidHT == null) { @@ -1203,11 +1188,13 @@ namespace System.Globalization { case -1: // call the private constructor - retval = new CultureInfo(name, altName); + Debug.Assert(name != null && altName != null); + retval = new CultureInfo(name!, altName!); break; case 0: - retval = new CultureInfo(name, false); + Debug.Assert(name != null); + retval = new CultureInfo(name!, false); break; default: @@ -1280,7 +1267,7 @@ namespace System.Globalization { throw new ArgumentOutOfRangeException(nameof(culture), SR.ArgumentOutOfRange_NeedPosNum); } - CultureInfo retval = GetCultureInfoHelper(culture, null, null); + CultureInfo? retval = GetCultureInfoHelper(culture, null, null); if (null == retval) { throw new CultureNotFoundException(nameof(culture), culture, SR.Argument_CultureNotSupported); @@ -1300,7 +1287,7 @@ namespace System.Globalization throw new ArgumentNullException(nameof(name)); } - CultureInfo retval = GetCultureInfoHelper(0, name, null); + CultureInfo? retval = GetCultureInfoHelper(0, name, null); if (retval == null) { throw new CultureNotFoundException( @@ -1324,7 +1311,7 @@ namespace System.Globalization throw new ArgumentNullException(nameof(altName)); } - CultureInfo retval = GetCultureInfoHelper(-1, name, altName); + CultureInfo? retval = GetCultureInfoHelper(-1, name, altName); if (retval == null) { throw new CultureNotFoundException("name or altName", diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureNotFoundException.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureNotFoundException.cs index 007aff7b9c..cb61d5079a 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/CultureNotFoundException.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureNotFoundException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Globalization @@ -10,7 +11,7 @@ namespace System.Globalization [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class CultureNotFoundException : ArgumentException { - private string _invalidCultureName; // unrecognized culture name + private string? _invalidCultureName; // unrecognized culture name private int? _invalidCultureId; // unrecognized culture Lcid public CultureNotFoundException() @@ -18,40 +19,40 @@ namespace System.Globalization { } - public CultureNotFoundException(string message) + public CultureNotFoundException(string? message) : base(message) { } - public CultureNotFoundException(string paramName, string message) + public CultureNotFoundException(string? paramName, string? message) : base(message, paramName) { } - public CultureNotFoundException(string message, Exception innerException) + public CultureNotFoundException(string? message, Exception? innerException) : base(message, innerException) { } - public CultureNotFoundException(string paramName, string invalidCultureName, string message) + public CultureNotFoundException(string? paramName, string? invalidCultureName, string? message) : base(message, paramName) { _invalidCultureName = invalidCultureName; } - public CultureNotFoundException(string message, string invalidCultureName, Exception innerException) + public CultureNotFoundException(string? message, string? invalidCultureName, Exception? innerException) : base(message, innerException) { _invalidCultureName = invalidCultureName; } - public CultureNotFoundException(string message, int invalidCultureId, Exception innerException) + public CultureNotFoundException(string? message, int invalidCultureId, Exception? innerException) : base(message, innerException) { _invalidCultureId = invalidCultureId; } - public CultureNotFoundException(string paramName, int invalidCultureId, string message) + public CultureNotFoundException(string? paramName, int invalidCultureId, string? message) : base(message, paramName) { _invalidCultureId = invalidCultureId; @@ -76,7 +77,7 @@ namespace System.Globalization get { return _invalidCultureId; } } - public virtual string InvalidCultureName + public virtual string? InvalidCultureName { get { return _invalidCultureName; } } @@ -89,7 +90,7 @@ namespace System.Globalization } } - private string FormatedInvalidCultureId + private string? FormattedInvalidCultureId { get { @@ -106,7 +107,7 @@ namespace System.Globalization string s = base.Message; if (_invalidCultureId != null || _invalidCultureName != null) { - string valueMessage = SR.Format(SR.Argument_CultureInvalidIdentifier, FormatedInvalidCultureId); + string valueMessage = SR.Format(SR.Argument_CultureInvalidIdentifier, FormattedInvalidCultureId); if (s == null) { return valueMessage; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs index 5bf9f4ef25..c2b20c46bf 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Globalization; @@ -220,7 +221,7 @@ namespace System { index++; } - return (index - pos); + return index - pos; } private static string FormatDayOfWeek(int dayOfWeek, int repeat, DateTimeFormatInfo dtfi) @@ -232,7 +233,7 @@ namespace System } // Call dtfi.GetDayName() here, instead of accessing DayNames property, because we don't // want a clone of DayNames, which will hurt perf. - return (dtfi.GetDayName((DayOfWeek)dayOfWeek)); + return dtfi.GetDayName((DayOfWeek)dayOfWeek); } private static string FormatMonth(int month, int repeatCount, DateTimeFormatInfo dtfi) @@ -240,11 +241,11 @@ namespace System Debug.Assert(month >= 1 && month <= 12, "month >=1 && month <= 12"); if (repeatCount == 3) { - return (dtfi.GetAbbreviatedMonthName(month)); + return dtfi.GetAbbreviatedMonthName(month); } // Call GetMonthName() here, instead of accessing MonthNames property, because we don't // want a clone of MonthNames, which will hurt perf. - return (dtfi.GetMonthName(month)); + return dtfi.GetMonthName(month); } // @@ -446,7 +447,7 @@ namespace System // Actions: Format the DateTime instance using the specified format. // private static StringBuilder FormatCustomized( - DateTime dateTime, ReadOnlySpan<char> format, DateTimeFormatInfo dtfi, TimeSpan offset, StringBuilder result) + DateTime dateTime, ReadOnlySpan<char> format, DateTimeFormatInfo dtfi, TimeSpan offset, StringBuilder? result) { Calendar cal = dtfi.Calendar; @@ -878,7 +879,7 @@ namespace System internal static string GetRealFormat(ReadOnlySpan<char> format, DateTimeFormatInfo dtfi) { - string realFormat = null; + string realFormat; switch (format[0]) { @@ -934,7 +935,7 @@ namespace System default: throw new FormatException(SR.Format_InvalidString); } - return (realFormat); + return realFormat; } @@ -1000,12 +1001,12 @@ namespace System return GetRealFormat(format, dtfi); } - internal static string Format(DateTime dateTime, string format, IFormatProvider provider) + internal static string Format(DateTime dateTime, string? format, IFormatProvider? provider) { return Format(dateTime, format, provider, NullOffset); } - internal static string Format(DateTime dateTime, string format, IFormatProvider provider, TimeSpan offset) + internal static string Format(DateTime dateTime, string? format, IFormatProvider? provider, TimeSpan offset) { if (format != null && format.Length == 1) { @@ -1036,10 +1037,10 @@ namespace System return StringBuilderCache.GetStringAndRelease(FormatStringBuilder(dateTime, format, dtfi, offset)); } - internal static bool TryFormat(DateTime dateTime, Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider provider) => + internal static bool TryFormat(DateTime dateTime, Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider) => TryFormat(dateTime, destination, out charsWritten, format, provider, NullOffset); - internal static bool TryFormat(DateTime dateTime, Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider provider, TimeSpan offset) + internal static bool TryFormat(DateTime dateTime, Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider, TimeSpan offset) { if (format.Length == 1) { @@ -1328,8 +1329,8 @@ namespace System internal static string[] GetAllDateTimes(DateTime dateTime, char format, DateTimeFormatInfo dtfi) { Debug.Assert(dtfi != null); - string[] allFormats = null; - string[] results = null; + string[] allFormats; + string[] results; switch (format) { @@ -1376,7 +1377,7 @@ namespace System default: throw new FormatException(SR.Format_InvalidString); } - return (results); + return results; } internal static string[] GetAllDateTimes(DateTime dateTime, DateTimeFormatInfo dtfi) diff --git a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs index 310771db02..78c97903ce 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -57,29 +58,29 @@ namespace System.Globalization private CultureData _cultureData; // The culture name used to create this DTFI. - private string _name = null; + private string? _name = null; // The language name of the culture used to create this DTFI. - private string _langName = null; + private string? _langName = null; // CompareInfo usually used by the parser. - private CompareInfo _compareInfo = null; + private CompareInfo? _compareInfo = null; // Culture matches current DTFI. mainly used for string comparisons during parsing. - private CultureInfo _cultureInfo = null; + private CultureInfo? _cultureInfo = null; - private string amDesignator = null; - private string pmDesignator = null; + private string? amDesignator = null; + private string? pmDesignator = null; - private string dateSeparator = null; // derived from short date (whidbey expects, arrowhead doesn't) + private string? dateSeparator = null; // derived from short date (whidbey expects, arrowhead doesn't) - private string generalShortTimePattern = null; // short date + short time (whidbey expects, arrowhead doesn't) + private string? generalShortTimePattern = null; // short date + short time (whidbey expects, arrowhead doesn't) - private string generalLongTimePattern = null; // short date + long time (whidbey expects, arrowhead doesn't) + private string? generalLongTimePattern = null; // short date + long time (whidbey expects, arrowhead doesn't) - private string timeSeparator = null; // derived from long time (whidbey expects, arrowhead doesn't) - private string monthDayPattern = null; - private string dateTimeOffsetPattern = null; + private string? timeSeparator = null; // derived from long time (whidbey expects, arrowhead doesn't) + private string? monthDayPattern = null; + private string? dateTimeOffsetPattern = null; private const string rfc1123Pattern = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'"; @@ -87,31 +88,31 @@ namespace System.Globalization private const string sortableDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss"; private const string universalSortableDateTimePattern = "yyyy'-'MM'-'dd HH':'mm':'ss'Z'"; - private Calendar calendar = null; + private Calendar calendar = null!; // initialized in helper called by ctors private int firstDayOfWeek = -1; private int calendarWeekRule = -1; - private string fullDateTimePattern = null; // long date + long time (whidbey expects, arrowhead doesn't) + private string? fullDateTimePattern = null; // long date + long time (whidbey expects, arrowhead doesn't) - private string[] abbreviatedDayNames = null; + private string[]? abbreviatedDayNames = null; - private string[] m_superShortDayNames = null; + private string[]? m_superShortDayNames = null; - private string[] dayNames = null; - private string[] abbreviatedMonthNames = null; - private string[] monthNames = null; + private string[]? dayNames = null; + private string[]? abbreviatedMonthNames = null; + private string[]? monthNames = null; // Cache the genitive month names that we retrieve from the data table. - private string[] genitiveMonthNames = null; + private string[]? genitiveMonthNames = null; // Cache the abbreviated genitive month names that we retrieve from the data table. - private string[] m_genitiveAbbreviatedMonthNames = null; + private string[]? m_genitiveAbbreviatedMonthNames = null; // Cache the month names of a leap year that we retrieve from the data table. - private string[] leapYearMonthNames = null; + private string[]? leapYearMonthNames = null; // For our "patterns" arrays we have 2 variables, a string and a string[] // @@ -120,25 +121,25 @@ namespace System.Globalization // When we initially construct our string[], we set the string to string[0] // The "default" Date/time patterns - private string longDatePattern = null; - private string shortDatePattern = null; - private string yearMonthPattern = null; - private string longTimePattern = null; - private string shortTimePattern = null; + private string? longDatePattern = null; + private string? shortDatePattern = null; + private string? yearMonthPattern = null; + private string? longTimePattern = null; + private string? shortTimePattern = null; - private string[] allYearMonthPatterns = null; + private string[]? allYearMonthPatterns = null; - private string[] allShortDatePatterns = null; - private string[] allLongDatePatterns = null; - private string[] allShortTimePatterns = null; - private string[] allLongTimePatterns = null; + private string[]? allShortDatePatterns = null; + private string[]? allLongDatePatterns = null; + private string[]? allShortTimePatterns = null; + private string[]? allLongTimePatterns = null; // Cache the era names for this DateTimeFormatInfo instance. - private string[] m_eraNames = null; - private string[] m_abbrevEraNames = null; - private string[] m_abbrevEnglishEraNames = null; + private string[]? m_eraNames = null; + private string[]? m_abbrevEraNames = null; + private string[]? m_abbrevEnglishEraNames = null; - private CalendarId[] optionalCalendars = null; + private CalendarId[]? optionalCalendars = null; private const int DEFAULT_ALL_DATETIMES_SIZE = 132; @@ -337,7 +338,6 @@ namespace System.Globalization /// <summary> /// Returns the current culture's DateTimeFormatInfo. /// </summary> - public static DateTimeFormatInfo CurrentInfo { get @@ -345,24 +345,24 @@ namespace System.Globalization System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CurrentCulture; if (!culture._isInherited) { - DateTimeFormatInfo info = culture._dateTimeInfo; + DateTimeFormatInfo? info = culture._dateTimeInfo; if (info != null) { return info; } } - return (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo)); + return (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo))!; } } - public static DateTimeFormatInfo GetInstance(IFormatProvider provider) => + public static DateTimeFormatInfo GetInstance(IFormatProvider? provider) => provider == null ? CurrentInfo : provider is CultureInfo cultureProvider && !cultureProvider._isInherited ? cultureProvider.DateTimeFormat : provider is DateTimeFormatInfo info ? info : provider.GetFormat(typeof(DateTimeFormatInfo)) is DateTimeFormatInfo info2 ? info2 : CurrentInfo; // Couldn't get anything, just use currentInfo as fallback - public object GetFormat(Type formatType) + public object? GetFormat(Type? formatType) { return formatType == typeof(DateTimeFormatInfo) ? this : null; } @@ -541,7 +541,7 @@ namespace System.Globalization for (int i = 0; i < EraNames.Length; i++) { // Compare the era name in a case-insensitive way for the appropriate culture. - if (m_eraNames[i].Length > 0) + if (m_eraNames![i].Length > 0) { if (Culture.CompareInfo.Compare(eraName, m_eraNames[i], CompareOptions.IgnoreCase) == 0) { @@ -552,7 +552,7 @@ namespace System.Globalization for (int i = 0; i < AbbreviatedEraNames.Length; i++) { // Compare the abbreviated era name in a case-insensitive way for the appropriate culture. - if (Culture.CompareInfo.Compare(eraName, m_abbrevEraNames[i], CompareOptions.IgnoreCase) == 0) + if (Culture.CompareInfo.Compare(eraName, m_abbrevEraNames![i], CompareOptions.IgnoreCase) == 0) { return i + 1; } @@ -561,7 +561,7 @@ namespace System.Globalization { // this comparison should use the InvariantCulture. The English name could have linguistically // interesting characters. - if (CompareInfo.Invariant.Compare(eraName, m_abbrevEnglishEraNames[i], CompareOptions.IgnoreCase) == 0) + if (CompareInfo.Invariant.Compare(eraName, m_abbrevEnglishEraNames![i], CompareOptions.IgnoreCase) == 0) { return i + 1; } @@ -597,7 +597,7 @@ namespace System.Globalization // If that ever changes, the code has to be changed. if ((--era) < EraNames.Length && (era >= 0)) { - return m_eraNames[era]; + return m_eraNames![era]; } throw new ArgumentOutOfRangeException(nameof(era), era, SR.ArgumentOutOfRange_InvalidEraValue); @@ -630,7 +630,7 @@ namespace System.Globalization { era = Calendar.CurrentEraValue; } - if ((--era) < m_abbrevEraNames.Length && (era >= 0)) + if ((--era) < m_abbrevEraNames!.Length && (era >= 0)) { return m_abbrevEraNames[era]; } @@ -738,7 +738,7 @@ namespace System.Globalization value, SR.Format(SR.ArgumentOutOfRange_Range, CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek)); } - + calendarWeekRule = (int)value; } } @@ -1255,7 +1255,7 @@ namespace System.Globalization { throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value)); } - + CheckNullValue(value, value.Length); ClearTokenHashTable(); @@ -1325,7 +1325,7 @@ namespace System.Globalization /// </summary> internal string InternalGetMonthName(int month, MonthNameStyles style, bool abbreviated) { - string[] monthNamesArray = null; + string[] monthNamesArray; switch (style) { case MonthNameStyles.Genitive: @@ -1474,7 +1474,7 @@ namespace System.Globalization public string[] GetAllDateTimePatterns(char format) { - string[] result = null; + string[] result; switch (format) { @@ -1919,14 +1919,14 @@ namespace System.Globalization } // Decimal separator used by positive TimeSpan pattern - private string _decimalSeparator; + private string? _decimalSeparator; internal string DecimalSeparator { get { if (_decimalSeparator == null) { - CultureData cultureDataWithoutUserOverrides = _cultureData.UseUserOverride ? + CultureData? cultureDataWithoutUserOverrides = _cultureData.UseUserOverride ? CultureData.GetCultureData(_cultureData.CultureName, false) : _cultureData; _decimalSeparator = new NumberFormatInfo(cultureDataWithoutUserOverrides).NumberDecimalSeparator; @@ -1936,7 +1936,7 @@ namespace System.Globalization } // Positive TimeSpan Pattern - private string _fullTimeSpanPositivePattern; + private string? _fullTimeSpanPositivePattern; internal string FullTimeSpanPositivePattern { get @@ -1950,7 +1950,7 @@ namespace System.Globalization } // Negative TimeSpan Pattern - private string _fullTimeSpanNegativePattern; + private string? _fullTimeSpanNegativePattern; internal string FullTimeSpanNegativePattern { get @@ -2098,7 +2098,7 @@ namespace System.Globalization } // DateTimeFormatInfo tokenizer. This is used by DateTime.Parse() to break input string into tokens. - private TokenHashValue[] _dtfiTokenHash; + private TokenHashValue[]? _dtfiTokenHash; private const int TOKEN_HASH_SIZE = 199; private const int SECOND_PRIME = 197; @@ -2190,7 +2190,7 @@ namespace System.Globalization internal TokenHashValue[] CreateTokenHashTable() { - TokenHashValue[] temp = _dtfiTokenHash; + TokenHashValue[]? temp = _dtfiTokenHash; if (temp == null) { temp = new TokenHashValue[TOKEN_HASH_SIZE]; @@ -2263,12 +2263,9 @@ namespace System.Globalization InsertHash(temp, dateSeparatorOrTimeZoneOffset, TokenType.SEP_DateOrOffset, 0); } - string[] dateWords = null; - DateTimeFormatInfoScanner scanner = null; - // We need to rescan the date words since we're always synthetic - scanner = new DateTimeFormatInfoScanner(); - dateWords = scanner.GetDateWordsOfDTFI(this); + DateTimeFormatInfoScanner scanner = new DateTimeFormatInfoScanner(); + string[]? dateWords = scanner.GetDateWordsOfDTFI(this); // Ensure the formatflags is initialized. DateTimeFormatFlags flag = FormatFlags; @@ -2593,7 +2590,7 @@ namespace System.Globalization int remaining = str.Length - str.Index; int i = 0; - TokenHashValue[] hashTable = _dtfiTokenHash; + TokenHashValue[]? hashTable = _dtfiTokenHash; if (hashTable == null) { hashTable = CreateTokenHashTable(); diff --git a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfoScanner.cs b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfoScanner.cs index d18bd3e4a8..a43bfe777b 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfoScanner.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfoScanner.cs @@ -19,6 +19,7 @@ // //////////////////////////////////////////////////////////////////////////// +#nullable enable using System.Collections.Generic; using System.Text; @@ -37,7 +38,7 @@ namespace System.Globalization UseSpacesInMonthNames = 0x00000004, UseHebrewParsing = 0x00000008, UseSpacesInDayNames = 0x00000010, // Has spaces or non-breaking space in the day names. - UseDigitPrefixInTokens = 0x00000020, // Has token starting with numbers. + UseDigitPrefixInTokens = 0x00000020, // Has token starting with numbers. } internal enum CalendarId : ushort @@ -47,7 +48,7 @@ namespace System.Globalization GREGORIAN_US = 2, // Gregorian (U.S.) calendar JAPAN = 3, // Japanese Emperor Era calendar /* SSS_WARNINGS_OFF */ - TAIWAN = 4, // Taiwan Era calendar /* SSS_WARNINGS_ON */ + TAIWAN = 4, // Taiwan Era calendar /* SSS_WARNINGS_ON */ KOREA = 5, // Korean Tangun Era calendar HIJRI = 6, // Hijri (Arabic Lunar) calendar THAI = 7, // Thai calendar @@ -126,7 +127,7 @@ namespace System.Globalization Dictionary<string, string> temp = new Dictionary<string, string>(); // Add known words into the hash table. - // Skip these special symbols. + // Skip these special symbols. temp.Add("/", string.Empty); temp.Add("-", string.Empty); temp.Add(".", string.Empty); @@ -204,14 +205,14 @@ namespace System.Globalization // A helper to add the found date word or month postfix into ArrayList for date words. // // Parameters: - // formatPostfix: What kind of postfix this is. + // formatPostfix: What kind of postfix this is. // Possible values: // null: This is a regular date word // "MMMM": month postfix // word: The date word or postfix to be added. // //////////////////////////////////////////////////////////////////////////// - internal void AddDateWordOrPostfix(string formatPostfix, string str) + internal void AddDateWordOrPostfix(string? formatPostfix, string str) { if (str.Length > 0) { @@ -269,10 +270,10 @@ namespace System.Globalization // Possible values: // null: This is a regular date word // "MMMM": month postfix - // + // // //////////////////////////////////////////////////////////////////////////// - internal int AddDateWords(string pattern, int index, string formatPostfix) + internal int AddDateWords(string pattern, int index, string? formatPostfix) { // Skip any whitespaces so we will start from a letter. int newIndex = SkipWhiteSpacesAndNonLetter(pattern, index); @@ -283,10 +284,10 @@ namespace System.Globalization } index = newIndex; - // This is the first char added into dateWord. + // This is the first char added into dateWord. // Skip all non-letter character. We will add the first letter into DateWord. StringBuilder dateWord = new StringBuilder(); - // We assume that date words should start with a letter. + // We assume that date words should start with a letter. // Skip anything until we see a letter. while (index < pattern.Length) @@ -294,8 +295,8 @@ namespace System.Globalization char ch = pattern[index]; if (ch == '\'') { - // We have seen the end of quote. Add the word if we do not see it before, - // and break the while loop. + // We have seen the end of quote. Add the word if we do not see it before, + // and break the while loop. AddDateWordOrPostfix(formatPostfix, dateWord.ToString()); index++; break; @@ -367,7 +368,7 @@ namespace System.Globalization // //////////////////////////////////////////////////////////////////////////// - internal void AddIgnorableSymbols(string text) + internal void AddIgnorableSymbols(string? text) { if (m_dateWords == null) { @@ -412,7 +413,7 @@ namespace System.Globalization // "\x0443." in bg-BG: dd.M.yyyy '\x0433.' // // Example of postfix: - // month postfix: + // month postfix: // "ta" in fi-FI: d. MMMM'ta 'yyyy // Currently, only month postfix is supported. // @@ -420,7 +421,7 @@ namespace System.Globalization // Always call this with Framework-style pattern, instead of Windows style pattern. // Windows style pattern uses '' for single quote, while .NET uses \' // - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// internal void ScanDateWord(string pattern) { // Check if we have found all of the year/month/day pattern. @@ -497,7 +498,7 @@ namespace System.Globalization // //////////////////////////////////////////////////////////////////////////// - internal string[] GetDateWordsOfDTFI(DateTimeFormatInfo dtfi) + internal string[]? GetDateWordsOfDTFI(DateTimeFormatInfo dtfi) { // Enumarate all LongDatePatterns, and get the DateWords and scan for month postfix. string[] datePatterns = dtfi.GetAllDateTimePatterns('D'); @@ -539,7 +540,7 @@ namespace System.Globalization ScanDateWord(datePatterns[i]); } - string[] result = null; + string[]? result = null; if (m_dateWords != null && m_dateWords.Count > 0) { result = new string[m_dateWords.Count]; @@ -548,16 +549,16 @@ namespace System.Globalization result[i] = m_dateWords[i]; } } - return (result); + return result; } - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// // // Scan the month names to see if genitive month names are used, and return // the format flag. // - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// internal static FORMATFLAGS GetFormatFlagGenitiveMonth(string[] monthNames, string[] genitveMonthNames, string[] abbrevMonthNames, string[] genetiveAbbrevMonthNames) { // If we have different names in regular and genitive month names, use genitive month flag. @@ -565,11 +566,11 @@ namespace System.Globalization ? FORMATFLAGS.UseGenitiveMonth : 0); } - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// // // Scan the month names to see if spaces are used or start with a digit, and return the format flag // - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// internal static FORMATFLAGS GetFormatFlagUseSpaceInMonthNames(string[] monthNames, string[] genitveMonthNames, string[] abbrevMonthNames, string[] genetiveAbbrevMonthNames) { FORMATFLAGS formatFlags = 0; @@ -587,11 +588,11 @@ namespace System.Globalization return (formatFlags); } - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// // // Scan the day names and set the correct format flag. // - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// internal static FORMATFLAGS GetFormatFlagUseSpaceInDayNames(string[] dayNames, string[] abbrevDayNames) { return ((ArrayElementsHaveSpace(dayNames) || @@ -599,11 +600,11 @@ namespace System.Globalization ? FORMATFLAGS.UseSpacesInDayNames : 0); } - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// // // Check the calendar to see if it is HebrewCalendar and set the Hebrew format flag if necessary. // - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// internal static FORMATFLAGS GetFormatFlagUseHebrewCalendar(int calID) { return (calID == (int)CalendarId.HEBREW ? @@ -612,9 +613,9 @@ namespace System.Globalization //----------------------------------------------------------------------------- - // EqualStringArrays - // compares two string arrays and return true if all elements of the first - // array equals to all elmentsof the second array. + // EqualStringArrays + // compares two string arrays and return true if all elements of the first + // array equals to all elmentsof the second array. // otherwise it returns false. //----------------------------------------------------------------------------- @@ -632,7 +633,7 @@ namespace System.Globalization return false; } - // Check each string + // Check each string for (int i = 0; i < array1.Length; i++) { if (array1[i] != array2[i]) @@ -645,7 +646,7 @@ namespace System.Globalization } //----------------------------------------------------------------------------- - // ArrayElementsHaveSpace + // ArrayElementsHaveSpace // It checks all input array elements if any of them has space character // returns true if found space character in one of the array elements. // otherwise returns false. @@ -670,11 +671,11 @@ namespace System.Globalization } - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// // // Check if any element of the array start with a digit. // - //////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// private static bool ArrayElementsBeginWithDigit(string[] array) { for (int i = 0; i < array.Length; i++) @@ -711,7 +712,7 @@ namespace System.Globalization if (index == array[i].Length - 4) { // Skip known CJK month suffix. - // Starting with Windows 8, the CJK months for some cultures looks like: "1' \x6708'" + // Starting with Windows 8, the CJK months for some cultures looks like: "1' \x6708'" // instead of just "1\x6708" if (array[i][index] == '\'' && array[i][index + 1] == ' ' && array[i][index + 2] == '\x6708' && array[i][index + 3] == '\'') diff --git a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs index 99cc413e26..76ee9085bf 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; @@ -5110,7 +5111,7 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR, return new FormatException(SR.Format(SR.GetResourceString(result.failureMessageID), new string(result.originalDateTimeString), result.failureMessageFormatArgument)); default: Debug.Fail("Unknown DateTimeParseFailure: " + result.failure.ToString()); - return null; + return null!; } } @@ -5996,7 +5997,7 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR, internal ParseFailureKind failure; internal string failureMessageID; - internal object failureMessageFormatArgument; + internal object? failureMessageFormatArgument; internal string failureArgumentName; internal ReadOnlySpan<char> originalDateTimeString; internal ReadOnlySpan<char> failedFormatSpecifier; @@ -6044,14 +6045,14 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR, this.failureMessageFormatArgument = null; } - internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument) + internal void SetFailure(ParseFailureKind failure, string failureMessageID, object? failureMessageFormatArgument) { this.failure = failure; this.failureMessageID = failureMessageID; this.failureMessageFormatArgument = failureMessageFormatArgument; } - internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument, string failureArgumentName) + internal void SetFailure(ParseFailureKind failure, string failureMessageID, object? failureMessageFormatArgument, string failureArgumentName) { this.failure = failure; this.failureMessageID = failureMessageID; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/DaylightTime.cs b/src/System.Private.CoreLib/shared/System/Globalization/DaylightTime.cs index 72a572c97d..0569b390c7 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/DaylightTime.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/DaylightTime.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Globalization { // This class represents a starting/ending time for a period of daylight saving time. diff --git a/src/System.Private.CoreLib/shared/System/Globalization/GlobalizationExtensions.cs b/src/System.Private.CoreLib/shared/System/Globalization/GlobalizationExtensions.cs index 007283aa6b..ed00cc58f6 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/GlobalizationExtensions.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/GlobalizationExtensions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Diagnostics; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendar.cs index 28bf46e5dd..68aba7e035 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendar.cs @@ -268,7 +268,7 @@ namespace System.Globalization public override int GetEra(DateTime time) => ADEra; - public override int[]? Eras => new int[] { ADEra }; + public override int[] Eras => new int[] { ADEra }; /// <summary> /// Returns the month part of the specified DateTime. diff --git a/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs b/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs index b7dd868258..5889dcb275 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Threading; @@ -19,9 +20,9 @@ namespace System.Globalization // be affected by the DateTime.MinValue; internal int maxEraYear; // Max year value in this era. (== the year length of the era + 1) - internal string eraName; // The era name - internal string abbrevEraName; // Abbreviated Era Name - internal string englishEraName; // English era name + internal string? eraName; // The era name + internal string? abbrevEraName; // Abbreviated Era Name + internal string? englishEraName; // English era name internal EraInfo(int era, int startYear, int startMonth, int startDay, int yearOffset, int minEraYear, int maxEraYear) { @@ -111,7 +112,7 @@ namespace System.Globalization internal Calendar m_Cal; internal EraInfo[] m_EraInfo; - internal int[] m_eras = null; + internal int[]? m_eras = null; // Construct an instance of gregorian calendar. @@ -668,4 +669,3 @@ namespace System.Globalization } } } - diff --git a/src/System.Private.CoreLib/shared/System/Globalization/HebrewCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/HebrewCalendar.cs index 497536629d..314c99816d 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/HebrewCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/HebrewCalendar.cs @@ -696,7 +696,7 @@ namespace System.Globalization public override int GetEra(DateTime time) => HebrewEra; - public override int[]? Eras => new int[] { HebrewEra }; + public override int[] Eras => new int[] { HebrewEra }; public override int GetMonth(DateTime time) { @@ -907,4 +907,3 @@ namespace System.Globalization } } } - diff --git a/src/System.Private.CoreLib/shared/System/Globalization/HebrewNumber.cs b/src/System.Private.CoreLib/shared/System/Globalization/HebrewNumber.cs index db9b379041..1919e82677 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/HebrewNumber.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/HebrewNumber.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Text; using System.Diagnostics; @@ -222,7 +223,7 @@ namespace System.Globalization Digit200_300 = 1, Digit100 = 2, Digit10 = 3, // 10 ~ 90 - Digit1 = 4, // 1, 2, 3, 4, 5, 8, + Digit1 = 4, // 1, 2, 3, 4, 5, 8, Digit6_7 = 5, Digit7 = 6, Digit9 = 7, @@ -262,7 +263,7 @@ namespace System.Globalization new HebrewValue(HebrewToken.Digit1, 8) , // '\x05d7 new HebrewValue(HebrewToken.Digit9, 9) , // '\x05d8 new HebrewValue(HebrewToken.Digit10, 10) , // '\x05d9; // Hebrew Letter Yod - new HebrewValue(HebrewToken.Invalid, -1) , // '\x05da; + new HebrewValue(HebrewToken.Invalid, -1) , // '\x05da; new HebrewValue(HebrewToken.Digit10, 20) , // '\x05db; // Hebrew Letter Kaf new HebrewValue(HebrewToken.Digit10, 30) , // '\x05dc; // Hebrew Letter Lamed new HebrewValue(HebrewToken.Invalid, -1) , // '\x05dd; @@ -315,7 +316,7 @@ namespace System.Globalization END = 100, // A terminial state is reached. } - // + // // The state machine for Hebrew number pasing. // private static readonly HS[] s_numberPasingState = @@ -361,7 +362,7 @@ namespace System.Globalization private const int HebrewTokenCount = 10; //////////////////////////////////////////////////////////////////////// - // + // // Actions: // Parse the Hebrew number by passing one character at a time. // The state between characters are maintained at HebrewNumberPasingContext. diff --git a/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.Win32.cs b/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.Win32.cs index d0b645ec1c..02e38e22ed 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.Win32.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.Win32.cs @@ -55,10 +55,10 @@ namespace System.Globalization } int hijriAdvance = 0; - string str = value.ToString(); + string? str = value.ToString(); if (string.Compare(str, 0, HijriAdvanceRegKeyEntry, 0, HijriAdvanceRegKeyEntry.Length, StringComparison.OrdinalIgnoreCase) == 0) { - if (str.Length == HijriAdvanceRegKeyEntry.Length) + if (str!.Length == HijriAdvanceRegKeyEntry.Length) hijriAdvance = -1; else { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.cs index f2a8aff252..41458c5a12 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.cs @@ -354,7 +354,7 @@ namespace System.Globalization return HijriEra; } - public override int[]? Eras => new int[] { HijriEra }; + public override int[] Eras => new int[] { HijriEra }; public override int GetMonth(DateTime time) { @@ -422,7 +422,7 @@ namespace System.Globalization { throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay); } - + return new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond)); } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/ISOWeek.cs b/src/System.Private.CoreLib/shared/System/Globalization/ISOWeek.cs index 3b3ba15ec8..89f5ca4a26 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/ISOWeek.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/ISOWeek.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using static System.Globalization.GregorianCalendar; namespace System.Globalization @@ -135,7 +136,7 @@ namespace System.Globalization int correction = GetWeekday(jan4.DayOfWeek) + 3; int ordinal = (week * 7) + GetWeekday(dayOfWeek) - correction; - + return new DateTime(year, month: 1, day: 1).AddDays(ordinal - 1); } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/IdnMapping.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/IdnMapping.Unix.cs index 20f753e986..4c8dcb8719 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/IdnMapping.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/IdnMapping.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Globalization @@ -122,7 +123,7 @@ namespace System.Globalization /// is enabled. /// /// To match Windows behavior, we walk the string ourselves looking for these - /// bad characters so we can continue to throw ArgumentException in these cases. + /// bad characters so we can continue to throw ArgumentException in these cases. /// </summary> private static unsafe void CheckInvalidIdnCharacters(char* s, int count, uint flags, string paramName) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/IdnMapping.Windows.cs b/src/System.Private.CoreLib/shared/System/Globalization/IdnMapping.Windows.cs index 9d491dfbb8..696abbcde1 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/IdnMapping.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/IdnMapping.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.InteropServices; @@ -119,10 +120,9 @@ namespace System.Globalization int lastError = Marshal.GetLastWin32Error(); throw new ArgumentException( - lastError == Interop.Errors.ERROR_INVALID_NAME ? SR.Argument_IdnIllegalName : + lastError == Interop.Errors.ERROR_INVALID_NAME ? SR.Argument_IdnIllegalName : (unicode ? SR.Argument_InvalidCharSequenceNoIndex : SR.Argument_IdnBadPunycode), unicode ? "unicode" : "ascii"); } } } - diff --git a/src/System.Private.CoreLib/shared/System/Globalization/IdnMapping.cs b/src/System.Private.CoreLib/shared/System/Globalization/IdnMapping.cs index 56f38ff628..9da4411f10 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/IdnMapping.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/IdnMapping.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable // This file contains the IDN functions and implementation. // // This allows encoding of non-ASCII domain names in a "punycode" form, @@ -143,7 +144,7 @@ namespace System.Globalization } } - public override bool Equals(object obj) + public override bool Equals(object? obj) { return obj is IdnMapping that && diff --git a/src/System.Private.CoreLib/shared/System/Globalization/InternalGlobalizationHelper.cs b/src/System.Private.CoreLib/shared/System/Globalization/InternalGlobalizationHelper.cs index 6dc2b19515..59fcd0f3c7 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/InternalGlobalizationHelper.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/InternalGlobalizationHelper.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Globalization { internal class InternalGlobalizationHelper diff --git a/src/System.Private.CoreLib/shared/System/Globalization/JapaneseCalendar.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/JapaneseCalendar.Unix.cs index 84bcedb2c8..364eeef059 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/JapaneseCalendar.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/JapaneseCalendar.Unix.cs @@ -17,13 +17,13 @@ namespace System.Globalization return null; } - string[] eraNames; + string[]? eraNames; if (!CalendarData.EnumCalendarInfo("ja-JP", CalendarId.JAPAN, CalendarDataType.EraNames, out eraNames)) { return null; } - string[] abbrevEnglishEraNames; + string[]? abbrevEnglishEraNames; if (!CalendarData.EnumCalendarInfo("en", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEnglishEraNames)) { return null; @@ -48,7 +48,7 @@ namespace System.Globalization } eras.Add(new EraInfo(i, dt.Year, dt.Month, dt.Day, dt.Year - 1, 1, lastMaxYear - dt.Year + 1, - eraNames[i], GetAbbreviatedEraName(eraNames, i), abbrevEnglishEraNames[i])); + eraNames![i], GetAbbreviatedEraName(eraNames, i), abbrevEnglishEraNames![i])); lastMaxYear = dt.Year; } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/JapaneseCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/JapaneseCalendar.cs index 0ee18b3fef..90f03d5613 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/JapaneseCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/JapaneseCalendar.cs @@ -115,7 +115,7 @@ namespace System.Globalization { return _helper.AddYears(time, years); } - + public override int GetDaysInMonth(int year, int month, int era) { return _helper.GetDaysInMonth(year, month, era); @@ -214,7 +214,7 @@ namespace System.Globalization } - public override int[]? Eras => _helper.Eras; + public override int[] Eras => _helper.Eras; /// <summary> /// Return the various era strings @@ -228,7 +228,7 @@ namespace System.Globalization for (int i = 0; i < eras.Length; i++) { // Strings are in chronological order, eras are backwards order. - eraNames[i] = eras[eras.Length - i - 1].eraName; + eraNames[i] = eras[eras.Length - i - 1].eraName!; } return eraNames; @@ -242,7 +242,7 @@ namespace System.Globalization for (int i = 0; i < eras.Length; i++) { // Strings are in chronological order, eras are backwards order. - erasAbbrev[i] = eras[eras.Length - i - 1].abbrevEraName; + erasAbbrev[i] = eras[eras.Length - i - 1].abbrevEraName!; } return erasAbbrev; @@ -256,7 +256,7 @@ namespace System.Globalization for (int i = 0; i < eras.Length; i++) { // Strings are in chronological order, eras are backwards order. - erasEnglish[i] = eras[eras.Length - i - 1].englishEraName; + erasEnglish[i] = eras[eras.Length - i - 1].englishEraName!; } return erasEnglish; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/JapaneseLunisolarCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/JapaneseLunisolarCalendar.cs index db1fd4f5b5..89e4e2beb5 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/JapaneseLunisolarCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/JapaneseLunisolarCalendar.cs @@ -27,7 +27,7 @@ namespace System.Globalization public override DateTime MinSupportedDateTime => s_minDate; public override DateTime MaxSupportedDateTime => s_maxDate; - + protected override int DaysInYearBeforeMinSupportedYear { get @@ -217,6 +217,6 @@ namespace System.Globalization internal override CalendarId ID => CalendarId.JAPANESELUNISOLAR; - public override int[]? Eras => _helper.Eras; + public override int[] Eras => _helper.Eras; } } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/JulianCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/JulianCalendar.cs index 79a06251da..782e197750 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/JulianCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/JulianCalendar.cs @@ -267,7 +267,7 @@ namespace System.Globalization return GetDatePart(time.Ticks, DatePartMonth); } - public override int[]? Eras => new int[] { JulianEra }; + public override int[] Eras => new int[] { JulianEra }; public override int GetMonthsInYear(int year, int era) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/KoreanCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/KoreanCalendar.cs index 4fbaa9f69b..a29f4d25e4 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/KoreanCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/KoreanCalendar.cs @@ -144,7 +144,7 @@ namespace System.Globalization return _helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era); } - public override int[]? Eras => _helper.Eras; + public override int[] Eras => _helper.Eras; private const int DefaultTwoDigitYearMax = 4362; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/KoreanLunisolarCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/KoreanLunisolarCalendar.cs index b7feb1a338..5871436ee0 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/KoreanLunisolarCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/KoreanLunisolarCalendar.cs @@ -1236,6 +1236,6 @@ namespace System.Globalization internal override CalendarId ID => CalendarId.KOREANLUNISOLAR; - public override int[]? Eras => new int[] { GregorianEra }; + public override int[] Eras => new int[] { GregorianEra }; } } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/LocaleData.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/LocaleData.Unix.cs index 2bd3d7905c..6b5049c2ba 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/LocaleData.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/LocaleData.Unix.cs @@ -2,9 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; -// This file contains the handling of Windows OS specific culture features. +// This file contains the handling of Windows OS specific culture features. namespace System.Globalization { @@ -15,12 +16,12 @@ namespace System.Globalization OemCodePage = 2, MacCodePage = 3, EbcdicCodePage = 4, - GeoId = 5, - DigitSubstitution = 6, - SpecificLocaleIndex = 7, + GeoId = 5, + DigitSubstitution = 6, + SpecificLocaleIndex = 7, ConsoleLocaleIndex = 8 } - + internal partial class LocaleData { // this is done rather than using a large readonly array of strings to avoid @@ -894,10 +895,10 @@ namespace System.Globalization "zh-tw_radstr" + // 40404 - 4265 "zu" + // 00035 - 4277 "zu-za"; // 00435 - 4279 - + // c_threeLetterWindowsLanguageName is string containing 3-letter Windows language names - // every 3-characters entry is matching locale name entry in c_localeNames - + // every 3-characters entry is matching locale name entry in c_localeNames + private const string c_threeLetterWindowsLanguageName = "ZZZ" + // aa "ZZZ" + // aa-dj @@ -2636,7 +2637,7 @@ namespace System.Globalization 4279, // 863 - zu-za 4284 }; - + private const int NUMERIC_LOCALE_DATA_COUNT_PER_ROW = 9; // s_nameIndexToNumericData is mapping from index in s_localeNamesIndices to locale data. // each row in the table will have the following data: @@ -3510,7 +3511,7 @@ namespace System.Globalization 0x435 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd1 , 1 , 863 , 863 , // 863 - zu-za }; - // s_lcids list all supported lcids. used to binary search and we use the index of the matched lcid to + // s_lcids list all supported lcids. used to binary search and we use the index of the matched lcid to // get the index in s_localeNamesIndices using s_lcidToCultureNameIndices private static readonly int[] s_lcids = new int[] { @@ -3963,7 +3964,7 @@ namespace System.Globalization 0x41404, // 445 - 4195 0x50804, // 446 - 4115 0x51004 // 447 - 4224 - }; + }; // each element in s_lcidToCultureNameIndices is index to s_localeNamesIndices private static readonly int[] s_lcidToCultureNameIndices = new int[] { @@ -4417,8 +4418,8 @@ namespace System.Globalization 845 , // 446 - 50804 - 4115 857 // 447 - 51004 - 4224 }; - - internal static string LCIDToLocaleName(int culture) + + internal static string? LCIDToLocaleName(int culture) { int left = 0; int right = s_lcids.Length - 1; @@ -4434,9 +4435,9 @@ namespace System.Globalization { int indexToLocaleNamesIndices = s_lcidToCultureNameIndices[index]; Debug.Assert(indexToLocaleNamesIndices < s_localeNamesIndices.Length - 1); - - return c_localeNames.Substring(s_localeNamesIndices[indexToLocaleNamesIndices], - s_localeNamesIndices[indexToLocaleNamesIndices + 1] - + + return c_localeNames.Substring(s_localeNamesIndices[indexToLocaleNamesIndices], + s_localeNamesIndices[indexToLocaleNamesIndices + 1] - s_localeNamesIndices[indexToLocaleNamesIndices]); } else if (culture < s_lcids[index]) @@ -4457,27 +4458,27 @@ namespace System.Globalization int index = SearchCultureName(cultureName); if (index < 0) { - return -1; + return -1; } - - Debug.Assert((s_localeNamesIndices.Length-1 == (s_nameIndexToNumericData.Length/NUMERIC_LOCALE_DATA_COUNT_PER_ROW)) && + + Debug.Assert((s_localeNamesIndices.Length-1 == (s_nameIndexToNumericData.Length/NUMERIC_LOCALE_DATA_COUNT_PER_ROW)) && index < s_localeNamesIndices.Length); - + return s_nameIndexToNumericData[index * NUMERIC_LOCALE_DATA_COUNT_PER_ROW + (int) part]; } - - internal static string GetThreeLetterWindowsLanguageName(string cultureName) + + internal static string? GetThreeLetterWindowsLanguageName(string cultureName) { int index = SearchCultureName(cultureName); if (index < 0) { return null; } - + Debug.Assert(s_localeNamesIndices.Length-1 == (c_threeLetterWindowsLanguageName.Length / 3)); - return c_threeLetterWindowsLanguageName.Substring(index * 3, 3); + return c_threeLetterWindowsLanguageName.Substring(index * 3, 3); } - + internal static string GetLocaleDataMappedCulture(string cultureName, LocaleDataParts part) { int indexToIndicesTable = GetLocaleDataNumericPart(cultureName, part); @@ -4485,25 +4486,25 @@ namespace System.Globalization { return ""; // fallback to invariant } - + Debug.Assert(indexToIndicesTable < s_localeNamesIndices.Length-1); - - return c_localeNames.Substring(s_localeNamesIndices[indexToIndicesTable], + + return c_localeNames.Substring(s_localeNamesIndices[indexToIndicesTable], s_localeNamesIndices[indexToIndicesTable+1] - s_localeNamesIndices[indexToIndicesTable]); } - + internal static string GetSpecificCultureName(string cultureName) { return GetLocaleDataMappedCulture(cultureName, LocaleDataParts.SpecificLocaleIndex); } - + internal static string GetConsoleUICulture(string cultureName) { return GetLocaleDataMappedCulture(cultureName, LocaleDataParts.ConsoleLocaleIndex); } - + // SearchCultureName will binary search c_localeNames using s_localeNamesIndices. - // return index in s_localeNamesIndices, or -1 if it fail finding any match + // return index in s_localeNamesIndices, or -1 if it fail finding any match private static int SearchCultureName(string name) { int left = 0; @@ -4550,7 +4551,7 @@ namespace System.Globalization // couldn't find culture name return -1; } - + // optimized to avoid parameters checking private static int CompareOrdinal(string s1, string s2, int index, int length) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/Normalization.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/Normalization.Unix.cs index 443dbae530..79a28322bc 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/Normalization.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/Normalization.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Text; @@ -13,7 +14,7 @@ namespace System.Globalization { if (GlobalizationMode.Invariant) { - // In Invariant mode we assume all characters are normalized. + // In Invariant mode we assume all characters are normalized. // This is because we don't support any linguistic operation on the strings return true; } @@ -34,7 +35,7 @@ namespace System.Globalization { if (GlobalizationMode.Invariant) { - // In Invariant mode we assume all characters are normalized. + // In Invariant mode we assume all characters are normalized. // This is because we don't support any linguistic operation on the strings return strInput; } @@ -95,7 +96,7 @@ namespace System.Globalization for (int i = 0; i < s.Length; i++) { char c = s[i]; - + if (c < '\ud800') { continue; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/Normalization.Windows.cs b/src/System.Private.CoreLib/shared/System/Globalization/Normalization.Windows.cs index 8418c53b6c..0b3ce0ec86 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/Normalization.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/Normalization.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; @@ -14,7 +15,7 @@ namespace System.Globalization { if (GlobalizationMode.Invariant) { - // In Invariant mode we assume all characters are normalized. + // In Invariant mode we assume all characters are normalized. // This is because we don't support any linguistic operation on the strings return true; } @@ -22,7 +23,7 @@ namespace System.Globalization Debug.Assert(strInput != null); // The only way to know if IsNormalizedString failed is through checking the Win32 last error - // IsNormalizedString pinvoke has SetLastError attribute property which will set the last error + // IsNormalizedString pinvoke has SetLastError attribute property which will set the last error // to 0 (ERROR_SUCCESS) before executing the calls. bool result = Interop.Normaliz.IsNormalizedString((int)normalizationForm, strInput, strInput.Length); @@ -34,9 +35,9 @@ namespace System.Globalization case Interop.Errors.ERROR_INVALID_PARAMETER: case Interop.Errors.ERROR_NO_UNICODE_TRANSLATION: - if (normalizationForm != NormalizationForm.FormC && - normalizationForm != NormalizationForm.FormD && - normalizationForm != NormalizationForm.FormKC && + if (normalizationForm != NormalizationForm.FormC && + normalizationForm != NormalizationForm.FormD && + normalizationForm != NormalizationForm.FormKC && normalizationForm != NormalizationForm.FormKD) { throw new ArgumentException(SR.Argument_InvalidNormalizationForm, nameof(normalizationForm)); @@ -58,7 +59,7 @@ namespace System.Globalization { if (GlobalizationMode.Invariant) { - // In Invariant mode we assume all characters are normalized. + // In Invariant mode we assume all characters are normalized. // This is because we don't support any linguistic operation on the strings return strInput; } @@ -66,7 +67,7 @@ namespace System.Globalization Debug.Assert(strInput != null); // we depend on Win32 last error when calling NormalizeString - // NormalizeString pinvoke has SetLastError attribute property which will set the last error + // NormalizeString pinvoke has SetLastError attribute property which will set the last error // to 0 (ERROR_SUCCESS) before executing the calls. // Guess our buffer size first @@ -78,9 +79,9 @@ namespace System.Globalization { if (lastError == Interop.Errors.ERROR_INVALID_PARAMETER) { - if (normalizationForm != NormalizationForm.FormC && - normalizationForm != NormalizationForm.FormD && - normalizationForm != NormalizationForm.FormKC && + if (normalizationForm != NormalizationForm.FormC && + normalizationForm != NormalizationForm.FormD && + normalizationForm != NormalizationForm.FormKC && normalizationForm != NormalizationForm.FormKD) { throw new ArgumentException(SR.Argument_InvalidNormalizationForm, nameof(normalizationForm)); @@ -103,14 +104,14 @@ namespace System.Globalization if (iLength == 0) return string.Empty; // Someplace to stick our buffer - char[] cBuffer = null; + char[] cBuffer; for (;;) { // (re)allocation buffer and normalize string cBuffer = new char[iLength]; - // NormalizeString pinvoke has SetLastError attribute property which will set the last error + // NormalizeString pinvoke has SetLastError attribute property which will set the last error // to 0 (ERROR_SUCCESS) before executing the calls. iLength = Interop.Normaliz.NormalizeString((int)normalizationForm, strInput, strInput.Length, cBuffer, cBuffer.Length); lastError = Marshal.GetLastWin32Error(); diff --git a/src/System.Private.CoreLib/shared/System/Globalization/NumberFormatInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/NumberFormatInfo.cs index 09030b9e07..bd490e42ad 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/NumberFormatInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/NumberFormatInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Globalization { /// <remarks> @@ -163,7 +164,7 @@ namespace System.Globalization _hasInvariantNumberSigns = _positiveSign == "+" && _negativeSign == "-"; } - internal NumberFormatInfo(CultureData cultureData) + internal NumberFormatInfo(CultureData? cultureData) { if (cultureData != null) { @@ -205,7 +206,7 @@ namespace System.Globalization } } - public static NumberFormatInfo GetInstance(IFormatProvider formatProvider) + public static NumberFormatInfo GetInstance(IFormatProvider? formatProvider) { return formatProvider == null ? CurrentInfo : // Fast path for a null provider @@ -384,13 +385,14 @@ namespace System.Globalization System.Globalization.CultureInfo culture = CultureInfo.CurrentCulture; if (!culture._isInherited) { - NumberFormatInfo info = culture._numInfo; + NumberFormatInfo? info = culture._numInfo; if (info != null) { return info; } } - return ((NumberFormatInfo)culture.GetFormat(typeof(NumberFormatInfo))); + // returns non-nullable when passed typeof(NumberFormatInfo) + return (NumberFormatInfo)culture.GetFormat(typeof(NumberFormatInfo))!; } } @@ -700,7 +702,7 @@ namespace System.Globalization } } - public object GetFormat(Type formatType) + public object? GetFormat(Type? formatType) { return formatType == typeof(NumberFormatInfo) ? this : null; } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/PersianCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/PersianCalendar.cs index 0858379749..0e43b15a12 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/PersianCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/PersianCalendar.cs @@ -282,7 +282,7 @@ namespace System.Globalization return PersianEra; } - public override int[]? Eras => new int[] { PersianEra }; + public override int[] Eras => new int[] { PersianEra }; public override int GetMonth(DateTime time) { diff --git a/src/System.Private.CoreLib/shared/System/Globalization/RegionInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/RegionInfo.cs index 03bed85c00..30471095f0 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/RegionInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/RegionInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Globalization @@ -21,7 +22,7 @@ namespace System.Globalization private readonly CultureData _cultureData; // The RegionInfo for our current region - internal static volatile RegionInfo s_currentRegionInfo; + internal static volatile RegionInfo? s_currentRegionInfo; public RegionInfo(string name) { @@ -37,11 +38,8 @@ namespace System.Globalization } // For CoreCLR we only want the region names that are full culture names - _cultureData = CultureData.GetCultureDataForRegion(name, true); - if (_cultureData == null) - { + _cultureData = CultureData.GetCultureDataForRegion(name, true) ?? throw new ArgumentException(SR.Format(SR.Argument_InvalidCultureName, name), nameof(name)); - } // Not supposed to be neutral if (_cultureData.IsNeutralCulture) @@ -49,7 +47,7 @@ namespace System.Globalization throw new ArgumentException(SR.Format(SR.Argument_InvalidNeutralRegionName, name), nameof(name)); } - SetName(name); + _name = _cultureData.RegionName; } public RegionInfo(int culture) @@ -88,12 +86,6 @@ namespace System.Globalization _name = _cultureData.RegionName; } - private void SetName(string name) - { - // Use the name of the region we found - _name = _cultureData.RegionName; - } - /// <summary> /// This instance provides methods based on the current user settings. /// These settings are volatile and may change over the lifetime of the @@ -102,7 +94,7 @@ namespace System.Globalization { get { - RegionInfo temp = s_currentRegionInfo; + RegionInfo? temp = s_currentRegionInfo; if (temp == null) { temp = new RegionInfo(CultureInfo.CurrentCulture._cultureData); @@ -194,7 +186,7 @@ namespace System.Globalization /// RegionInfos are considered equal if and only if they have the same name /// (ie: en-US) /// </summary> - public override bool Equals(object value) + public override bool Equals(object? value) { return value is RegionInfo otherRegion && Name.Equals(otherRegion.Name); diff --git a/src/System.Private.CoreLib/shared/System/Globalization/SortKey.cs b/src/System.Private.CoreLib/shared/System/Globalization/SortKey.cs index b00f34b814..f75b4f74ab 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/SortKey.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/SortKey.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Globalization @@ -92,7 +93,7 @@ namespace System.Globalization return 0; } - public override bool Equals(object value) + public override bool Equals(object? value) { return value is SortKey otherSortKey && Compare(this, otherSortKey) == 0; } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/SortVersion.cs b/src/System.Private.CoreLib/shared/System/Globalization/SortVersion.cs index ce86d56932..23cf8b37d7 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/SortVersion.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/SortVersion.cs @@ -2,13 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; namespace System.Globalization { [Serializable] [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - public sealed class SortVersion : IEquatable<SortVersion> + public sealed class SortVersion : IEquatable<SortVersion?> { private int m_NlsVersion; // Do not rename (binary serialization) private Guid m_SortId; // Do not rename (binary serialization) @@ -39,12 +40,12 @@ namespace System.Globalization m_SortId = customVersion; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { return obj is SortVersion otherVersion && Equals(otherVersion); } - public bool Equals(SortVersion other) + public bool Equals(SortVersion? other) { if (other == null) { @@ -61,7 +62,7 @@ namespace System.Globalization // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(SortVersion left, SortVersion right) + public static bool operator ==(SortVersion? left, SortVersion? right) { // Test "right" first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test @@ -74,7 +75,7 @@ namespace System.Globalization return right.Equals(left); } - public static bool operator !=(SortVersion left, SortVersion right) + public static bool operator !=(SortVersion? left, SortVersion? right) { return !(left == right); } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/StringInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/StringInfo.cs index 2c9b4da5cc..fe5db920ef 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/StringInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/StringInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Globalization @@ -13,9 +14,9 @@ namespace System.Globalization /// </summary> public class StringInfo { - private string _str; + private string _str = null!; // initialized in helper called by ctors - private int[] _indexes; + private int[]? _indexes; public StringInfo() : this(string.Empty) { @@ -26,7 +27,7 @@ namespace System.Globalization this.String = value; } - public override bool Equals(object value) + public override bool Equals(object? value) { return value is StringInfo otherStringInfo && _str.Equals(otherStringInfo._str); @@ -35,10 +36,10 @@ namespace System.Globalization public override int GetHashCode() => _str.GetHashCode(); /// <summary> - /// Our zero-based array of index values into the string. Initialize if + /// Our zero-based array of index values into the string. Initialize if /// our private array is not yet, in fact, initialized. /// </summary> - private int[] Indexes + private int[]? Indexes { get { @@ -65,7 +66,7 @@ namespace System.Globalization public string SubstringByTextElements(int startingTextElement) { - // If the string is empty, no sense going further. + // If the string is empty, no sense going further. if (Indexes == null) { if (startingTextElement < 0) @@ -87,7 +88,7 @@ namespace System.Globalization { throw new ArgumentOutOfRangeException(nameof(startingTextElement), startingTextElement, SR.ArgumentOutOfRange_NeedPosNum); } - if (String.Length == 0 || startingTextElement >= Indexes.Length) + if (String.Length == 0 || startingTextElement >= Indexes!.Length) { throw new ArgumentOutOfRangeException(nameof(startingTextElement), startingTextElement, SR.Arg_ArgumentOutOfRangeException); } @@ -126,7 +127,7 @@ namespace System.Globalization /// * EnclosingMark (e.g. U+20DD COMBINING ENCLOSING CIRCLE) /// /// In the context of GetNextTextElement() and ParseCombiningCharacters(), a text element is defined as: - /// 1. If a character/surrogate is in the following category, it is a text element. + /// 1. If a character/surrogate is in the following category, it is a text element. /// It can NOT further combine with characters in the combinging class to form a text element. /// * one of the Unicode category in the combinging class /// * UnicodeCategory.Format @@ -196,9 +197,9 @@ namespace System.Globalization } /// <summary> - /// Returns the str containing the next text element in str starting at - /// index index. If index is not supplied, then it will start at the beginning - /// of str. It recognizes a base character plus one or more combining + /// Returns the str containing the next text element in str starting at + /// index index. If index is not supplied, then it will start at the beginning + /// of str. It recognizes a base character plus one or more combining /// characters or a properly formed surrogate pair as a text element. /// See also the ParseCombiningCharacters() and the ParseSurrogates() methods. /// </summary> diff --git a/src/System.Private.CoreLib/shared/System/Globalization/TaiwanCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/TaiwanCalendar.cs index 6d7fb4177e..de541a30c4 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/TaiwanCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/TaiwanCalendar.cs @@ -28,7 +28,7 @@ namespace System.Globalization // So yearOffset = 1911 private static EraInfo[] s_taiwanEraInfo = new EraInfo[] { - new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear + new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear }; private static volatile Calendar s_defaultInstance; @@ -149,7 +149,7 @@ namespace System.Globalization return _helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era); } - public override int[]? Eras => _helper.Eras; + public override int[] Eras => _helper.Eras; private const int DefaultTwoDigitYearMax = 99; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/TaiwanLunisolarCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/TaiwanLunisolarCalendar.cs index 826f0f389c..47dbc3b0af 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/TaiwanLunisolarCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/TaiwanLunisolarCalendar.cs @@ -21,7 +21,7 @@ namespace System.Globalization // So yearOffset = 1911 private static readonly EraInfo[] s_taiwanLunisolarEraInfo = new EraInfo[] { - new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear + new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear }; private readonly GregorianCalendarHelper _helper; @@ -235,6 +235,6 @@ namespace System.Globalization internal override CalendarId ID => CalendarId.TAIWANLUNISOLAR; - public override int[]? Eras => _helper.Eras; + public override int[] Eras => _helper.Eras; } } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/TextElementEnumerator.cs b/src/System.Private.CoreLib/shared/System/Globalization/TextElementEnumerator.cs index 60d2a1055a..7b0136b808 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/TextElementEnumerator.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/TextElementEnumerator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections; using System.Diagnostics; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.Unix.cs index 45cf55c56e..5f75e6c050 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.InteropServices; using System.Security; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.Windows.cs b/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.Windows.cs index d0c859400b..b59648dae5 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Globalization diff --git a/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.cs index 12ce6d9696..cf89dff6a2 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -33,7 +34,7 @@ namespace System.Globalization True = 2 } - private string _listSeparator; + private string? _listSeparator; private bool _isReadOnly = false; private readonly string _cultureName; @@ -50,7 +51,7 @@ namespace System.Globalization get => s_invariant ?? (s_invariant = new TextInfo(CultureData.Invariant)); } - private volatile static TextInfo s_invariant; + private volatile static TextInfo? s_invariant; internal TextInfo(CultureData cultureData) { @@ -602,7 +603,7 @@ namespace System.Globalization /// </summary> public bool IsRightToLeft => _cultureData.IsRightToLeft; - public override bool Equals(object obj) + public override bool Equals(object? obj) { return obj is TextInfo otherTextInfo && CultureName.Equals(otherTextInfo.CultureName); @@ -640,7 +641,7 @@ namespace System.Globalization } StringBuilder result = new StringBuilder(); - string lowercaseData = null; + string? lowercaseData = null; // Store if the current culture is Dutch (special case) bool isDutchCulture = CultureName.StartsWith("nl-", StringComparison.OrdinalIgnoreCase); diff --git a/src/System.Private.CoreLib/shared/System/Globalization/ThaiBuddhistCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/ThaiBuddhistCalendar.cs index 1b39c7b247..8997f00f26 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/ThaiBuddhistCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/ThaiBuddhistCalendar.cs @@ -125,7 +125,7 @@ namespace System.Globalization return _helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era); } - public override int[]? Eras => _helper.Eras; + public override int[] Eras => _helper.Eras; private const int DefaultTwoDigitYearMax = 2572; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/TimeSpanFormat.cs b/src/System.Private.CoreLib/shared/System/Globalization/TimeSpanFormat.cs index ccb42ad87c..376827e6fd 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/TimeSpanFormat.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/TimeSpanFormat.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers.Text; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -39,7 +40,7 @@ namespace System.Globalization /// <summary>Main method called from TimeSpan.ToString.</summary> - internal static string Format(TimeSpan value, string format, IFormatProvider formatProvider) + internal static string Format(TimeSpan value, string? format, IFormatProvider? formatProvider) { if (string.IsNullOrEmpty(format)) { @@ -67,7 +68,7 @@ namespace System.Globalization } /// <summary>Main method called from TimeSpan.TryFormat.</summary> - internal static bool TryFormat(TimeSpan value, Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider formatProvider) + internal static bool TryFormat(TimeSpan value, Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? formatProvider) { if (format.Length == 0) { @@ -126,7 +127,7 @@ namespace System.Globalization private enum StandardFormat { C, G, g } - private static bool TryFormatStandard(TimeSpan value, StandardFormat format, string decimalSeparator, Span<char> destination, out int charsWritten) + private static bool TryFormatStandard(TimeSpan value, StandardFormat format, string? decimalSeparator, Span<char> destination, out int charsWritten) { Debug.Assert(format == StandardFormat.C || format == StandardFormat.G || format == StandardFormat.g); @@ -281,11 +282,12 @@ namespace System.Globalization // Write fraction and separator, if necessary if (fractionDigits != 0) { + Debug.Assert(format == StandardFormat.C || decimalSeparator != null); if (format == StandardFormat.C) { destination[idx++] = '.'; } - else if (decimalSeparator.Length == 1) + else if (decimalSeparator!.Length == 1) { destination[idx++] = decimalSeparator[0]; } @@ -330,7 +332,7 @@ namespace System.Globalization } /// <summary>Format the TimeSpan instance using the specified format.</summary> - private static StringBuilder FormatCustomized(TimeSpan value, ReadOnlySpan<char> format, DateTimeFormatInfo dtfi, StringBuilder result = null) + private static StringBuilder FormatCustomized(TimeSpan value, ReadOnlySpan<char> format, DateTimeFormatInfo dtfi, StringBuilder? result = null) { Debug.Assert(dtfi != null); @@ -390,7 +392,7 @@ namespace System.Globalization break; case 'f': // - // The fraction of a second in single-digit precision. The remaining digits are truncated. + // The fraction of a second in single-digit precision. The remaining digits are truncated. // tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch); if (tokenLen > DateTimeFormat.MaxSecondsFractionDigits) @@ -451,7 +453,7 @@ namespace System.Globalization break; case '%': // Optional format character. - // For example, format string "%d" will print day + // For example, format string "%d" will print day // Most of the cases, "%" can be ignored. nextChar = DateTimeFormat.ParseNextChar(format, i); // nextChar will be -1 if we already reach the end of the format string. @@ -532,7 +534,7 @@ namespace System.Globalization x._literals[3] = ":"; x._literals[4] = "."; x._literals[5] = string.Empty; - x.AppCompatLiteral = ":."; // MinuteSecondSep+SecondFractionSep; + x.AppCompatLiteral = ":."; // MinuteSecondSep+SecondFractionSep; x.dd = 2; x.hh = 2; x.mm = 2; diff --git a/src/System.Private.CoreLib/shared/System/Globalization/TimeSpanParse.cs b/src/System.Private.CoreLib/shared/System/Globalization/TimeSpanParse.cs index a9172e2802..39defa0b66 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/TimeSpanParse.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/TimeSpanParse.cs @@ -48,6 +48,7 @@ // //////////////////////////////////////////////////////////////////////////// +#nullable enable using System.Diagnostics; using System.Text; @@ -611,7 +612,7 @@ namespace System.Globalization return true; } - internal static TimeSpan Parse(ReadOnlySpan<char> input, IFormatProvider formatProvider) + internal static TimeSpan Parse(ReadOnlySpan<char> input, IFormatProvider? formatProvider) { var parseResult = new TimeSpanResult(throwOnFailure: true, originalTimeSpanString: input); bool success = TryParseTimeSpan(input, TimeSpanStandardStyles.Any, formatProvider, ref parseResult); @@ -619,7 +620,7 @@ namespace System.Globalization return parseResult.parsedTimeSpan; } - internal static bool TryParse(ReadOnlySpan<char> input, IFormatProvider formatProvider, out TimeSpan result) + internal static bool TryParse(ReadOnlySpan<char> input, IFormatProvider? formatProvider, out TimeSpan result) { var parseResult = new TimeSpanResult(throwOnFailure: false, originalTimeSpanString: input); @@ -633,7 +634,7 @@ namespace System.Globalization return false; } - internal static TimeSpan ParseExact(ReadOnlySpan<char> input, ReadOnlySpan<char> format, IFormatProvider formatProvider, TimeSpanStyles styles) + internal static TimeSpan ParseExact(ReadOnlySpan<char> input, ReadOnlySpan<char> format, IFormatProvider? formatProvider, TimeSpanStyles styles) { var parseResult = new TimeSpanResult(throwOnFailure: true, originalTimeSpanString: input); bool success = TryParseExactTimeSpan(input, format, formatProvider, styles, ref parseResult); @@ -641,7 +642,7 @@ namespace System.Globalization return parseResult.parsedTimeSpan; } - internal static bool TryParseExact(ReadOnlySpan<char> input, ReadOnlySpan<char> format, IFormatProvider formatProvider, TimeSpanStyles styles, out TimeSpan result) + internal static bool TryParseExact(ReadOnlySpan<char> input, ReadOnlySpan<char> format, IFormatProvider? formatProvider, TimeSpanStyles styles, out TimeSpan result) { var parseResult = new TimeSpanResult(throwOnFailure: false, originalTimeSpanString: input); @@ -655,7 +656,7 @@ namespace System.Globalization return false; } - internal static TimeSpan ParseExactMultiple(ReadOnlySpan<char> input, string[] formats, IFormatProvider formatProvider, TimeSpanStyles styles) + internal static TimeSpan ParseExactMultiple(ReadOnlySpan<char> input, string?[] formats, IFormatProvider? formatProvider, TimeSpanStyles styles) { var parseResult = new TimeSpanResult(throwOnFailure: true, originalTimeSpanString: input); bool success = TryParseExactMultipleTimeSpan(input, formats, formatProvider, styles, ref parseResult); @@ -663,7 +664,7 @@ namespace System.Globalization return parseResult.parsedTimeSpan; } - internal static bool TryParseExactMultiple(ReadOnlySpan<char> input, string[] formats, IFormatProvider formatProvider, TimeSpanStyles styles, out TimeSpan result) + internal static bool TryParseExactMultiple(ReadOnlySpan<char> input, string?[] formats, IFormatProvider? formatProvider, TimeSpanStyles styles, out TimeSpan result) { var parseResult = new TimeSpanResult(throwOnFailure: false, originalTimeSpanString: input); @@ -678,7 +679,7 @@ namespace System.Globalization } /// <summary>Common private Parse method called by both Parse and TryParse.</summary> - private static bool TryParseTimeSpan(ReadOnlySpan<char> input, TimeSpanStandardStyles style, IFormatProvider formatProvider, ref TimeSpanResult result) + private static bool TryParseTimeSpan(ReadOnlySpan<char> input, TimeSpanStandardStyles style, IFormatProvider? formatProvider, ref TimeSpanResult result) { input = input.Trim(); if (input.IsEmpty) @@ -1215,7 +1216,7 @@ namespace System.Globalization } /// <summary>Common private ParseExact method called by both ParseExact and TryParseExact.</summary> - private static bool TryParseExactTimeSpan(ReadOnlySpan<char> input, ReadOnlySpan<char> format, IFormatProvider formatProvider, TimeSpanStyles styles, ref TimeSpanResult result) + private static bool TryParseExactTimeSpan(ReadOnlySpan<char> input, ReadOnlySpan<char> format, IFormatProvider? formatProvider, TimeSpanStyles styles, ref TimeSpanResult result) { if (format.Length == 0) { @@ -1669,7 +1670,7 @@ namespace System.Globalization } /// <summary>Common private ParseExactMultiple method called by both ParseExactMultiple and TryParseExactMultiple.</summary> - private static bool TryParseExactMultipleTimeSpan(ReadOnlySpan<char> input, string[] formats, IFormatProvider formatProvider, TimeSpanStyles styles, ref TimeSpanResult result) + private static bool TryParseExactMultipleTimeSpan(ReadOnlySpan<char> input, string?[] formats, IFormatProvider? formatProvider, TimeSpanStyles styles, ref TimeSpanResult result) { if (formats == null) { @@ -1690,7 +1691,8 @@ namespace System.Globalization // one of the formats. for (int i = 0; i < formats.Length; i++) { - if (formats[i] == null || formats[i].Length == 0) + // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34644 + if (formats[i] == null || formats[i]!.Length == 0) { return result.SetBadFormatSpecifierFailure(); } diff --git a/src/System.Private.CoreLib/shared/System/Globalization/UmAlQuraCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/UmAlQuraCalendar.cs index 8af839fd33..49d7e893ac 100644 --- a/src/System.Private.CoreLib/shared/System/Globalization/UmAlQuraCalendar.cs +++ b/src/System.Private.CoreLib/shared/System/Globalization/UmAlQuraCalendar.cs @@ -520,7 +520,7 @@ namespace System.Globalization return UmAlQuraEra; } - public override int[]? Eras => new int[] { UmAlQuraEra }; + public override int[] Eras => new int[] { UmAlQuraEra }; public override int GetMonth(DateTime time) { diff --git a/src/System.Private.CoreLib/shared/System/IAsyncResult.cs b/src/System.Private.CoreLib/shared/System/IAsyncResult.cs index 56ebcdb2f5..8d7b32327e 100644 --- a/src/System.Private.CoreLib/shared/System/IAsyncResult.cs +++ b/src/System.Private.CoreLib/shared/System/IAsyncResult.cs @@ -11,7 +11,7 @@ ** ===========================================================*/ -using System; +#nullable enable using System.Threading; namespace System @@ -23,7 +23,7 @@ namespace System WaitHandle AsyncWaitHandle { get; } - object AsyncState { get; } + object? AsyncState { get; } bool CompletedSynchronously { get; } } diff --git a/src/System.Private.CoreLib/shared/System/IO/DirectoryNotFoundException.cs b/src/System.Private.CoreLib/shared/System/IO/DirectoryNotFoundException.cs index d7c6eacb9a..58d4ee1a3f 100644 --- a/src/System.Private.CoreLib/shared/System/IO/DirectoryNotFoundException.cs +++ b/src/System.Private.CoreLib/shared/System/IO/DirectoryNotFoundException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.IO @@ -22,13 +23,13 @@ namespace System.IO HResult = HResults.COR_E_DIRECTORYNOTFOUND; } - public DirectoryNotFoundException(string message) + public DirectoryNotFoundException(string? message) : base(message) { HResult = HResults.COR_E_DIRECTORYNOTFOUND; } - public DirectoryNotFoundException(string message, Exception innerException) + public DirectoryNotFoundException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_DIRECTORYNOTFOUND; diff --git a/src/System.Private.CoreLib/shared/System/IO/EndOfStreamException.cs b/src/System.Private.CoreLib/shared/System/IO/EndOfStreamException.cs index 606073ad9a..69759aac1b 100644 --- a/src/System.Private.CoreLib/shared/System/IO/EndOfStreamException.cs +++ b/src/System.Private.CoreLib/shared/System/IO/EndOfStreamException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.IO @@ -16,13 +17,13 @@ namespace System.IO HResult = HResults.COR_E_ENDOFSTREAM; } - public EndOfStreamException(string message) + public EndOfStreamException(string? message) : base(message) { HResult = HResults.COR_E_ENDOFSTREAM; } - public EndOfStreamException(string message, Exception innerException) + public EndOfStreamException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_ENDOFSTREAM; diff --git a/src/System.Private.CoreLib/shared/System/IO/FileLoadException.cs b/src/System.Private.CoreLib/shared/System/IO/FileLoadException.cs index 8c31244e1d..a893aca47b 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileLoadException.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileLoadException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.IO @@ -16,25 +17,25 @@ namespace System.IO HResult = HResults.COR_E_FILELOAD; } - public FileLoadException(string message) + public FileLoadException(string? message) : base(message) { HResult = HResults.COR_E_FILELOAD; } - public FileLoadException(string message, Exception inner) + public FileLoadException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_FILELOAD; } - public FileLoadException(string message, string fileName) : base(message) + public FileLoadException(string? message, string? fileName) : base(message) { HResult = HResults.COR_E_FILELOAD; FileName = fileName; } - public FileLoadException(string message, string fileName, Exception inner) + public FileLoadException(string? message, string? fileName, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_FILELOAD; @@ -53,8 +54,8 @@ namespace System.IO } } - public string FileName { get; } - public string FusionLog { get; } + public string? FileName { get; } + public string? FusionLog { get; } public override string ToString() { diff --git a/src/System.Private.CoreLib/shared/System/IO/FileNotFoundException.cs b/src/System.Private.CoreLib/shared/System/IO/FileNotFoundException.cs index 72cff4cfc0..9ab3eb38e5 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileNotFoundException.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileNotFoundException.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable +using System.Diagnostics; using System.Runtime.Serialization; namespace System.IO @@ -17,26 +19,26 @@ namespace System.IO HResult = HResults.COR_E_FILENOTFOUND; } - public FileNotFoundException(string message) + public FileNotFoundException(string? message) : base(message) { HResult = HResults.COR_E_FILENOTFOUND; } - public FileNotFoundException(string message, Exception innerException) + public FileNotFoundException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_FILENOTFOUND; } - public FileNotFoundException(string message, string fileName) + public FileNotFoundException(string? message, string? fileName) : base(message) { HResult = HResults.COR_E_FILENOTFOUND; FileName = fileName; } - public FileNotFoundException(string message, string fileName, Exception innerException) + public FileNotFoundException(string? message, string? fileName, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_FILENOTFOUND; @@ -48,6 +50,7 @@ namespace System.IO get { SetMessageField(); + Debug.Assert(_message != null, "_message was null after calling SetMessageField"); return _message; } } @@ -65,8 +68,8 @@ namespace System.IO } } - public string FileName { get; } - public string FusionLog { get; } + public string? FileName { get; } + public string? FusionLog { get; } public override string ToString() { diff --git a/src/System.Private.CoreLib/shared/System/IO/FileStream.Linux.cs b/src/System.Private.CoreLib/shared/System/IO/FileStream.Linux.cs index 873c4eb559..33207fc602 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileStream.Linux.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileStream.Linux.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Microsoft.Win32.SafeHandles; using System.Diagnostics; using System.Threading; diff --git a/src/System.Private.CoreLib/shared/System/IO/FileStream.OSX.cs b/src/System.Private.CoreLib/shared/System/IO/FileStream.OSX.cs index f29e922337..c8e4c9086d 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileStream.OSX.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileStream.OSX.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.IO { public partial class FileStream : Stream diff --git a/src/System.Private.CoreLib/shared/System/IO/FileStream.Unix.cs b/src/System.Private.CoreLib/shared/System/IO/FileStream.Unix.cs index 6bbd037137..62e1fdec25 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileStream.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileStream.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Microsoft.Win32.SafeHandles; using System.Diagnostics; using System.Runtime.InteropServices; @@ -29,7 +30,7 @@ namespace System.IO /// synchronously from ReadAsync which can be reused if the count matches the next request. /// Only initialized when <see cref="_useAsyncIO"/> is true. /// </summary> - private AsyncState _asyncState; + private AsyncState? _asyncState; /// <summary>Lazily-initialized value for whether the file supports seeking.</summary> private bool? _canSeek; @@ -290,7 +291,7 @@ namespace System.IO // override may already exist on a derived type. if (_useAsyncIO && _writePos > 0) { - return new ValueTask(Task.Factory.StartNew(s => ((FileStream)s).Dispose(), this, + return new ValueTask(Task.Factory.StartNew(s => ((FileStream)s!).Dispose(), this, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default)); } @@ -364,7 +365,7 @@ namespace System.IO if (CanWrite) { return Task.Factory.StartNew( - state => ((FileStream)state).FlushOSBuffer(), + state => ((FileStream)state!).FlushOSBuffer(), // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 this, cancellationToken, TaskCreationOptions.DenyChildAttach, @@ -507,9 +508,10 @@ namespace System.IO /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <param name="synchronousResult">If the operation completes synchronously, the number of bytes read.</param> /// <returns>A task that represents the asynchronous read operation.</returns> - private Task<int> ReadAsyncInternal(Memory<byte> destination, CancellationToken cancellationToken, out int synchronousResult) + private Task<int>? ReadAsyncInternal(Memory<byte> destination, CancellationToken cancellationToken, out int synchronousResult) { Debug.Assert(_useAsyncIO); + Debug.Assert(_asyncState != null); if (!CanRead) // match Windows behavior; this gets thrown synchronously { @@ -567,7 +569,8 @@ namespace System.IO // whereas on Windows it may happen before the write has completed. Debug.Assert(t.Status == TaskStatus.RanToCompletion); - var thisRef = (FileStream)s; + var thisRef = (FileStream)s!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 + Debug.Assert(thisRef._asyncState != null); try { Memory<byte> memory = thisRef._asyncState.Memory; @@ -668,6 +671,7 @@ namespace System.IO private ValueTask WriteAsyncInternal(ReadOnlyMemory<byte> source, CancellationToken cancellationToken) { Debug.Assert(_useAsyncIO); + Debug.Assert(_asyncState != null); if (cancellationToken.IsCancellationRequested) return new ValueTask(Task.FromCanceled(cancellationToken)); @@ -724,7 +728,8 @@ namespace System.IO // whereas on Windows it may happen before the write has completed. Debug.Assert(t.Status == TaskStatus.RanToCompletion); - var thisRef = (FileStream)s; + var thisRef = (FileStream)s!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 + Debug.Assert(thisRef._asyncState != null); try { ReadOnlyMemory<byte> readOnlyMemory = thisRef._asyncState.ReadOnlyMemory; diff --git a/src/System.Private.CoreLib/shared/System/IO/FileStream.Win32.cs b/src/System.Private.CoreLib/shared/System/IO/FileStream.Win32.cs index 1c371d54e1..e3361aec62 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileStream.Win32.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileStream.Win32.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using Microsoft.Win32.SafeHandles; diff --git a/src/System.Private.CoreLib/shared/System/IO/FileStream.WinRT.cs b/src/System.Private.CoreLib/shared/System/IO/FileStream.WinRT.cs index b326525a7d..752a6d9d8a 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileStream.WinRT.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileStream.WinRT.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Microsoft.Win32.SafeHandles; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/System/IO/FileStream.Windows.cs b/src/System.Private.CoreLib/shared/System/IO/FileStream.Windows.cs index f7592282c0..4de7a3b254 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileStream.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileStream.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers; using System.Diagnostics; using System.Runtime.InteropServices; @@ -46,11 +47,11 @@ namespace System.IO private bool _isPipe; // Whether to disable async buffering code. private long _appendStart; // When appending, prevent overwriting file. - private static unsafe IOCompletionCallback s_ioCallback = FileStreamCompletionSource.IOCallback; + private static readonly unsafe IOCompletionCallback s_ioCallback = FileStreamCompletionSource.IOCallback; - private Task _activeBufferOperation = null; // tracks in-progress async ops using the buffer - private PreAllocatedOverlapped _preallocatedOverlapped; // optimization for async ops to avoid per-op allocations - private FileStreamCompletionSource _currentOverlappedOwner; // async op currently using the preallocated overlapped + private Task _activeBufferOperation = Task.CompletedTask; // tracks in-progress async ops using the buffer + private PreAllocatedOverlapped? _preallocatedOverlapped; // optimization for async ops to avoid per-op allocations + private FileStreamCompletionSource? _currentOverlappedOwner; // async op currently using the preallocated overlapped private void Init(FileMode mode, FileShare share, string originalPath) { @@ -196,8 +197,7 @@ namespace System.IO return secAttrs; } - private bool HasActiveBufferOperation - => _activeBufferOperation != null && !_activeBufferOperation.IsCompleted; + private bool HasActiveBufferOperation => !_activeBufferOperation.IsCompleted; public override bool CanSeek => _canSeek; @@ -406,7 +406,8 @@ namespace System.IO // Instance method to help code external to this MarshalByRefObject avoid // accessing its fields by ref. This avoids a compiler warning. - private FileStreamCompletionSource CompareExchangeCurrentOverlappedOwner(FileStreamCompletionSource newSource, FileStreamCompletionSource existingSource) => Interlocked.CompareExchange(ref _currentOverlappedOwner, newSource, existingSource); + private FileStreamCompletionSource? CompareExchangeCurrentOverlappedOwner(FileStreamCompletionSource? newSource, FileStreamCompletionSource? existingSource) => + Interlocked.CompareExchange(ref _currentOverlappedOwner, newSource, existingSource); private int ReadSpan(Span<byte> destination) { @@ -732,7 +733,7 @@ namespace System.IO return; } - private Task<int> ReadAsyncInternal(Memory<byte> destination, CancellationToken cancellationToken, out int synchronousResult) + private Task<int>? ReadAsyncInternal(Memory<byte> destination, CancellationToken cancellationToken, out int synchronousResult) { Debug.Assert(_useAsyncIO); if (!CanRead) throw Error.GetReadNotSupported(); @@ -1024,7 +1025,7 @@ namespace System.IO // We return a Task that represents one or both. // Flush the buffer asynchronously if there's anything to flush - Task flushTask = null; + Task? flushTask = null; if (_writePos > 0) { flushTask = FlushWriteAsync(cancellationToken); @@ -1341,6 +1342,7 @@ namespace System.IO { cancellationReg = cancellationToken.UnsafeRegister(s => { + Debug.Assert(s is AsyncCopyToAwaitable); var innerAwaitable = (AsyncCopyToAwaitable)s; unsafe { @@ -1492,7 +1494,7 @@ namespace System.IO /// s_sentinel if the I/O operation completed before the await, /// s_callback if it completed after the await yielded. /// </summary> - internal Action _continuation; + internal Action? _continuation; /// <summary>Last error code from completed operation.</summary> internal uint _errorCode; /// <summary>Last number of read bytes from completed operation.</summary> @@ -1519,7 +1521,8 @@ namespace System.IO /// <summary>Overlapped callback: store the results, then invoke the continuation delegate.</summary> internal static unsafe void IOCallback(uint errorCode, uint numBytes, NativeOverlapped* pOVERLAP) { - var awaitable = (AsyncCopyToAwaitable)ThreadPoolBoundHandle.GetNativeOverlappedState(pOVERLAP); + var awaitable = (AsyncCopyToAwaitable?)ThreadPoolBoundHandle.GetNativeOverlappedState(pOVERLAP); + Debug.Assert(awaitable != null); Debug.Assert(!ReferenceEquals(awaitable._continuation, s_sentinel), "Sentinel must not have already been set as the continuation"); awaitable._errorCode = errorCode; @@ -1585,7 +1588,7 @@ namespace System.IO if (CanWrite) { return Task.Factory.StartNew( - state => ((FileStream)state).FlushOSBuffer(), + state => ((FileStream)state!).FlushOSBuffer(), // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 this, cancellationToken, TaskCreationOptions.DenyChildAttach, @@ -1634,7 +1637,7 @@ namespace System.IO // probably be consistent w/ every other directory. int errorCode = Marshal.GetLastWin32Error(); - if (errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND && _path.Length == PathInternal.GetRootLength(_path)) + if (errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND && _path!.Length == PathInternal.GetRootLength(_path)) errorCode = Interop.Errors.ERROR_ACCESS_DENIED; throw Win32Marshal.GetExceptionForWin32Error(errorCode, _path); diff --git a/src/System.Private.CoreLib/shared/System/IO/FileStream.cs b/src/System.Private.CoreLib/shared/System/IO/FileStream.cs index bc84d98c50..0f75f36948 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileStream.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileStream.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; @@ -16,15 +17,15 @@ namespace System.IO private const bool DefaultIsAsync = false; internal const int DefaultBufferSize = 4096; - private byte[] _buffer; + private byte[]? _buffer; private int _bufferLength; - private readonly SafeFileHandle _fileHandle; + private readonly SafeFileHandle _fileHandle; // only ever null if ctor throws /// <summary>Whether the file is opened for reading, writing, or both.</summary> private readonly FileAccess _access; /// <summary>The path to the opened file.</summary> - private readonly string _path; + private readonly string? _path; /// <summary>The next available byte to be read from the _buffer.</summary> private int _readPos; @@ -53,7 +54,7 @@ namespace System.IO private readonly bool _useAsyncIO; /// <summary>cached task for read ops that complete synchronously</summary> - private Task<int> _lastSynchronouslyCompletedTask = null; + private Task<int>? _lastSynchronouslyCompletedTask = null; /// <summary> /// Currently cached position in the stream. This should always mirror the underlying file's actual position, @@ -191,7 +192,7 @@ namespace System.IO // don't include inheritable in our bounds check for share FileShare tempshare = share & ~FileShare.Inheritable; - string badArg = null; + string? badArg = null; if (mode < FileMode.CreateNew || mode > FileMode.Append) badArg = nameof(mode); @@ -248,7 +249,7 @@ namespace System.IO // If anything goes wrong while setting up the stream, make sure we deterministically dispose // of the opened handle. _fileHandle.Dispose(); - _fileHandle = null; + _fileHandle = null!; throw; } } @@ -377,7 +378,7 @@ namespace System.IO throw Error.GetFileNotOpen(); } - Task<int> t = ReadAsyncInternal(buffer, cancellationToken, out int synchronousResult); + Task<int>? t = ReadAsyncInternal(buffer, cancellationToken, out int synchronousResult); return t != null ? new ValueTask<int>(t) : new ValueTask<int>(synchronousResult); @@ -385,7 +386,7 @@ namespace System.IO private Task<int> ReadAsyncTask(byte[] array, int offset, int count, CancellationToken cancellationToken) { - Task<int> t = ReadAsyncInternal(new Memory<byte>(array, offset, count), cancellationToken, out int synchronousResult); + Task<int>? t = ReadAsyncInternal(new Memory<byte>(array, offset, count), cancellationToken, out int synchronousResult); if (t == null) { @@ -818,7 +819,7 @@ namespace System.IO Dispose(false); } - public override IAsyncResult BeginRead(byte[] array, int offset, int numBytes, AsyncCallback callback, object state) + public override IAsyncResult BeginRead(byte[] array, int offset, int numBytes, AsyncCallback callback, object? state) { if (array == null) throw new ArgumentNullException(nameof(array)); @@ -838,7 +839,7 @@ namespace System.IO return TaskToApm.Begin(ReadAsyncTask(array, offset, numBytes, CancellationToken.None), callback, state); } - public override IAsyncResult BeginWrite(byte[] array, int offset, int numBytes, AsyncCallback callback, object state) + public override IAsyncResult BeginWrite(byte[] array, int offset, int numBytes, AsyncCallback callback, object? state) { if (array == null) throw new ArgumentNullException(nameof(array)); diff --git a/src/System.Private.CoreLib/shared/System/IO/FileStreamCompletionSource.Win32.cs b/src/System.Private.CoreLib/shared/System/IO/FileStreamCompletionSource.Win32.cs index a7996fd042..54756a2edc 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileStreamCompletionSource.Win32.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileStreamCompletionSource.Win32.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Buffers; using System.Diagnostics; using System.Runtime.InteropServices; @@ -24,7 +25,7 @@ namespace System.IO private const long CompletedCallback = (long)8 << 32; private const ulong ResultMask = ((ulong)uint.MaxValue) << 32; - private static Action<object> s_cancelCallback; + private static Action<object?> s_cancelCallback; private readonly FileStream _stream; private readonly int _numBufferedBytes; @@ -36,7 +37,7 @@ namespace System.IO private long _result; // Using long since this needs to be used in Interlocked APIs // Using RunContinuationsAsynchronously for compat reasons (old API used Task.Factory.StartNew for continuations) - protected FileStreamCompletionSource(FileStream stream, int numBufferedBytes, byte[] bytes) + protected FileStreamCompletionSource(FileStream stream, int numBufferedBytes, byte[]? bytes) : base(TaskCreationOptions.RunContinuationsAsynchronously) { _numBufferedBytes = numBufferedBytes; @@ -48,12 +49,12 @@ namespace System.IO // thus is already pinned) and if no one else is currently using the preallocated overlapped. This is the fast-path // for cases where the user-provided buffer is smaller than the FileStream's buffer (such that the FileStream's // buffer is used) and where operations on the FileStream are not being performed concurrently. - Debug.Assert((bytes == null || ReferenceEquals(bytes, _stream._buffer))); + Debug.Assert(bytes == null || ReferenceEquals(bytes, _stream._buffer)); // The _preallocatedOverlapped is null if the internal buffer was never created, so we check for // a non-null bytes before using the stream's _preallocatedOverlapped _overlapped = bytes != null && _stream.CompareExchangeCurrentOverlappedOwner(this, null) == null ? - _stream._fileHandle.ThreadPoolBinding.AllocateNativeOverlapped(_stream._preallocatedOverlapped) : + _stream._fileHandle.ThreadPoolBinding.AllocateNativeOverlapped(_stream._preallocatedOverlapped!) : // allocated when buffer was created, and buffer is non-null _stream._fileHandle.ThreadPoolBinding.AllocateNativeOverlapped(s_ioCallback, this, bytes); Debug.Assert(_overlapped != null, "AllocateNativeOverlapped returned null"); } @@ -132,14 +133,16 @@ namespace System.IO internal static unsafe void IOCallback(uint errorCode, uint numBytes, NativeOverlapped* pOverlapped) { // Extract the completion source from the overlapped. The state in the overlapped - // will either be a Win32FileStream (in the case where the preallocated overlapped was used), + // will either be a FileStream (in the case where the preallocated overlapped was used), // in which case the operation being completed is its _currentOverlappedOwner, or it'll - // be directly the FileStreamCompletion that's completing (in the case where the preallocated + // be directly the FileStreamCompletionSource that's completing (in the case where the preallocated // overlapped was already in use by another operation). - object state = ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped); + object? state = ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped); + Debug.Assert(state is FileStream || state is FileStreamCompletionSource); FileStreamCompletionSource completionSource = state is FileStream fs ? - fs._currentOverlappedOwner : - (FileStreamCompletionSource)state; + fs._currentOverlappedOwner! : // must be owned + (FileStreamCompletionSource)state!; + Debug.Assert(completionSource != null); Debug.Assert(completionSource._overlapped == pOverlapped, "Overlaps don't match"); // Handle reading from & writing to closed pipes. While I'm not sure @@ -198,12 +201,12 @@ namespace System.IO } } - private static void Cancel(object state) + private static void Cancel(object? state) { // WARNING: This may potentially be called under a lock (during cancellation registration) - FileStreamCompletionSource completionSource = state as FileStreamCompletionSource; - Debug.Assert(completionSource != null, "Unknown state passed to cancellation"); + Debug.Assert(state is FileStreamCompletionSource, "Unknown state passed to cancellation"); + FileStreamCompletionSource completionSource = (FileStreamCompletionSource)state; Debug.Assert(completionSource._overlapped != null && !completionSource.Task.IsCompleted, "IO should not have completed yet"); // If the handle is still valid, attempt to cancel the IO diff --git a/src/System.Private.CoreLib/shared/System/IO/IOException.cs b/src/System.Private.CoreLib/shared/System/IO/IOException.cs index 04e6532061..ba8525f043 100644 --- a/src/System.Private.CoreLib/shared/System/IO/IOException.cs +++ b/src/System.Private.CoreLib/shared/System/IO/IOException.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +#nullable enable using System.Runtime.Serialization; namespace System.IO @@ -17,19 +17,19 @@ namespace System.IO HResult = HResults.COR_E_IO; } - public IOException(string message) + public IOException(string? message) : base(message) { HResult = HResults.COR_E_IO; } - public IOException(string message, int hresult) + public IOException(string? message, int hresult) : base(message) { HResult = hresult; } - public IOException(string message, Exception innerException) + public IOException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_IO; diff --git a/src/System.Private.CoreLib/shared/System/IO/MemoryStream.cs b/src/System.Private.CoreLib/shared/System/IO/MemoryStream.cs index c8b72d45f8..bb9fa29adc 100644 --- a/src/System.Private.CoreLib/shared/System/IO/MemoryStream.cs +++ b/src/System.Private.CoreLib/shared/System/IO/MemoryStream.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -32,7 +33,7 @@ namespace System.IO private bool _exposable; // Whether the array can be returned to the user. private bool _isOpen; // Is this stream open or closed? - private Task<int> _lastReadTask; // The last successful task returned from ReadAsync + private Task<int>? _lastReadTask; // The last successful task returned from ReadAsync private const int MemStreamMaxLength = int.MaxValue; diff --git a/src/System.Private.CoreLib/shared/System/IO/PathTooLongException.cs b/src/System.Private.CoreLib/shared/System/IO/PathTooLongException.cs index 7af2452736..e0a35f7c9e 100644 --- a/src/System.Private.CoreLib/shared/System/IO/PathTooLongException.cs +++ b/src/System.Private.CoreLib/shared/System/IO/PathTooLongException.cs @@ -2,8 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - -using System; +#nullable enable using System.Runtime.Serialization; namespace System.IO @@ -18,13 +17,13 @@ namespace System.IO HResult = HResults.COR_E_PATHTOOLONG; } - public PathTooLongException(string message) + public PathTooLongException(string? message) : base(message) { HResult = HResults.COR_E_PATHTOOLONG; } - public PathTooLongException(string message, Exception innerException) + public PathTooLongException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_PATHTOOLONG; diff --git a/src/System.Private.CoreLib/shared/System/IO/PinnedBufferMemoryStream.cs b/src/System.Private.CoreLib/shared/System/IO/PinnedBufferMemoryStream.cs index 94331a2ef8..7c636b9527 100644 --- a/src/System.Private.CoreLib/shared/System/IO/PinnedBufferMemoryStream.cs +++ b/src/System.Private.CoreLib/shared/System/IO/PinnedBufferMemoryStream.cs @@ -14,6 +14,7 @@ ** ===========================================================*/ +#nullable enable using System; using System.Runtime.InteropServices; using System.Diagnostics; diff --git a/src/System.Private.CoreLib/shared/System/IO/Stream.cs b/src/System.Private.CoreLib/shared/System/IO/Stream.cs index 537d28ca8a..1f0943f2fc 100644 --- a/src/System.Private.CoreLib/shared/System/IO/Stream.cs +++ b/src/System.Private.CoreLib/shared/System/IO/Stream.cs @@ -15,9 +15,9 @@ ** ===========================================================*/ +#nullable enable using System.Buffers; using System.Diagnostics; -using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; using System.Threading; @@ -36,14 +36,14 @@ namespace System.IO // To implement Async IO operations on streams that don't support async IO - private ReadWriteTask _activeReadWriteTask; - private SemaphoreSlim _asyncActiveSemaphore; + private ReadWriteTask? _activeReadWriteTask; + private SemaphoreSlim? _asyncActiveSemaphore; internal SemaphoreSlim EnsureAsyncActiveSemaphoreInitialized() { // Lazily-initialize _asyncActiveSemaphore. As we're never accessing the SemaphoreSlim's // WaitHandle, we don't need to worry about Disposing it. - return LazyInitializer.EnsureInitialized(ref _asyncActiveSemaphore, () => new SemaphoreSlim(1, 1)); + return LazyInitializer.EnsureInitialized<SemaphoreSlim>(ref _asyncActiveSemaphore!, () => new SemaphoreSlim(1, 1)); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } public abstract bool CanRead @@ -256,7 +256,7 @@ namespace System.IO public virtual Task FlushAsync(CancellationToken cancellationToken) { - return Task.Factory.StartNew(state => ((Stream)state).Flush(), this, + return Task.Factory.StartNew(state => ((Stream)state!).Flush(), this, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } @@ -266,13 +266,13 @@ namespace System.IO return new ManualResetEvent(false); } - public virtual IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + public virtual IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object? state) { return BeginReadInternal(buffer, offset, count, callback, state, serializeAsynchronously: false, apm: true); } internal IAsyncResult BeginReadInternal( - byte[] buffer, int offset, int count, AsyncCallback callback, object state, + byte[] buffer, int offset, int count, AsyncCallback? callback, object? state, bool serializeAsynchronously, bool apm) { if (!CanRead) throw Error.GetReadNotSupported(); @@ -283,7 +283,7 @@ namespace System.IO // async requests outstanding, we will block the application's main // thread if it does a second IO request until the first one completes. var semaphore = EnsureAsyncActiveSemaphoreInitialized(); - Task semaphoreTask = null; + Task? semaphoreTask = null; if (serializeAsynchronously) { semaphoreTask = semaphore.WaitAsync(); @@ -301,7 +301,8 @@ namespace System.IO // As we're currently inside of it, we can get the current task // and grab the parameters from it. var thisTask = Task.InternalCurrent as ReadWriteTask; - Debug.Assert(thisTask != null, "Inside ReadWriteTask, InternalCurrent should be the ReadWriteTask"); + Debug.Assert(thisTask != null && thisTask._stream != null && thisTask._buffer != null, + "Inside ReadWriteTask, InternalCurrent should be the ReadWriteTask, and stream and buffer should be set"); try { @@ -428,13 +429,13 @@ namespace System.IO - public virtual IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + public virtual IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object? state) { return BeginWriteInternal(buffer, offset, count, callback, state, serializeAsynchronously: false, apm: true); } internal IAsyncResult BeginWriteInternal( - byte[] buffer, int offset, int count, AsyncCallback callback, object state, + byte[] buffer, int offset, int count, AsyncCallback? callback, object? state, bool serializeAsynchronously, bool apm) { if (!CanWrite) throw Error.GetWriteNotSupported(); @@ -445,7 +446,7 @@ namespace System.IO // async requests outstanding, we will block the application's main // thread if it does a second IO request until the first one completes. var semaphore = EnsureAsyncActiveSemaphoreInitialized(); - Task semaphoreTask = null; + Task? semaphoreTask = null; if (serializeAsynchronously) { semaphoreTask = semaphore.WaitAsync(); // kick off the asynchronous wait, but don't block @@ -463,7 +464,8 @@ namespace System.IO // As we're currently inside of it, we can get the current task // and grab the parameters from it. var thisTask = Task.InternalCurrent as ReadWriteTask; - Debug.Assert(thisTask != null, "Inside ReadWriteTask, InternalCurrent should be the ReadWriteTask"); + Debug.Assert(thisTask != null && thisTask._stream != null && thisTask._buffer != null, + "Inside ReadWriteTask, InternalCurrent should be the ReadWriteTask, and stream and buffer should be set"); try { @@ -510,7 +512,8 @@ namespace System.IO asyncWaiter.ContinueWith((t, state) => { Debug.Assert(t.IsCompletedSuccessfully, "The semaphore wait should always complete successfully."); - var rwt = (ReadWriteTask)state; + var rwt = (ReadWriteTask)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 + Debug.Assert(rwt._stream != null); rwt._stream.RunReadWriteTask(rwt); // RunReadWriteTask(readWriteTask); }, readWriteTask, default, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); } @@ -587,12 +590,12 @@ namespace System.IO { internal readonly bool _isRead; internal readonly bool _apm; // true if this is from Begin/EndXx; false if it's from XxAsync - internal Stream _stream; - internal byte[] _buffer; + internal Stream? _stream; + internal byte[]? _buffer; internal readonly int _offset; internal readonly int _count; - private AsyncCallback _callback; - private ExecutionContext _context; + private AsyncCallback? _callback; + private ExecutionContext? _context; internal void ClearBeginState() // Used to allow the args to Read/Write to be made available for GC { @@ -603,8 +606,8 @@ namespace System.IO public ReadWriteTask( bool isRead, bool apm, - Func<object, int> function, object state, - Stream stream, byte[] buffer, int offset, int count, AsyncCallback callback) : + Func<object?, int> function, object? state, + Stream stream, byte[] buffer, int offset, int count, AsyncCallback? callback) : base(function, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach) { Debug.Assert(function != null); @@ -632,10 +635,12 @@ namespace System.IO } } - private static void InvokeAsyncCallback(object completedTask) + private static void InvokeAsyncCallback(object? completedTask) { + Debug.Assert(completedTask is ReadWriteTask); var rwc = (ReadWriteTask)completedTask; var callback = rwc._callback; + Debug.Assert(callback != null); rwc._callback = null; callback(rwc); } @@ -651,6 +656,7 @@ namespace System.IO if (context == null) { var callback = _callback; + Debug.Assert(callback != null); _callback = null; callback(completingTask); } @@ -805,7 +811,7 @@ namespace System.IO { } - internal IAsyncResult BlockingBeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + internal IAsyncResult BlockingBeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object? state) { // To avoid a race with a stream's position pointer & generating conditions // with internal buffer indexes in our own streams that @@ -837,7 +843,7 @@ namespace System.IO return SynchronousAsyncResult.EndRead(asyncResult); } - internal IAsyncResult BlockingBeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + internal IAsyncResult BlockingBeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object? state) { // To avoid a race condition with a stream's position pointer & generating conditions // with internal buffer indexes in our own streams that @@ -923,7 +929,7 @@ namespace System.IO Task.CompletedTask; } - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object? state) { if (!CanRead) throw Error.GetReadNotSupported(); @@ -938,7 +944,7 @@ namespace System.IO return BlockingEndRead(asyncResult); } - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object? state) { if (!CanWrite) throw Error.GetWriteNotSupported(); @@ -1018,28 +1024,28 @@ namespace System.IO /// <summary>Used as the IAsyncResult object when using asynchronous IO methods on the base Stream class.</summary> private sealed class SynchronousAsyncResult : IAsyncResult { - private readonly object _stateObject; + private readonly object? _stateObject; private readonly bool _isWrite; - private ManualResetEvent _waitHandle; - private ExceptionDispatchInfo _exceptionInfo; + private ManualResetEvent? _waitHandle; + private ExceptionDispatchInfo? _exceptionInfo; private bool _endXxxCalled; private int _bytesRead; - internal SynchronousAsyncResult(int bytesRead, object asyncStateObject) + internal SynchronousAsyncResult(int bytesRead, object? asyncStateObject) { _bytesRead = bytesRead; _stateObject = asyncStateObject; //_isWrite = false; } - internal SynchronousAsyncResult(object asyncStateObject) + internal SynchronousAsyncResult(object? asyncStateObject) { _stateObject = asyncStateObject; _isWrite = true; } - internal SynchronousAsyncResult(Exception ex, object asyncStateObject, bool isWrite) + internal SynchronousAsyncResult(Exception ex, object? asyncStateObject, bool isWrite) { _exceptionInfo = ExceptionDispatchInfo.Capture(ex); _stateObject = asyncStateObject; @@ -1056,11 +1062,11 @@ namespace System.IO { get { - return LazyInitializer.EnsureInitialized(ref _waitHandle, () => new ManualResetEvent(true)); + return LazyInitializer.EnsureInitialized<ManualResetEvent>(ref _waitHandle!, () => new ManualResetEvent(true)); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } } - public object AsyncState + public object? AsyncState { get { return _stateObject; } } @@ -1243,7 +1249,7 @@ namespace System.IO return _stream.ReadByte(); } - public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object? state) { #if CORERT throw new NotImplementedException(); // TODO: https://github.com/dotnet/corert/issues/3251 @@ -1304,7 +1310,7 @@ namespace System.IO _stream.WriteByte(b); } - public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object? state) { #if CORERT throw new NotImplementedException(); // TODO: https://github.com/dotnet/corert/issues/3251 diff --git a/src/System.Private.CoreLib/shared/System/IO/StreamHelpers.CopyValidation.cs b/src/System.Private.CoreLib/shared/System/IO/StreamHelpers.CopyValidation.cs index 45bbd816df..fe849fbef2 100644 --- a/src/System.Private.CoreLib/shared/System/IO/StreamHelpers.CopyValidation.cs +++ b/src/System.Private.CoreLib/shared/System/IO/StreamHelpers.CopyValidation.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.IO { /// <summary>Provides methods to help in the implementation of Stream-derived types.</summary> diff --git a/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStream.cs b/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStream.cs index 8ebf606627..8489d66286 100644 --- a/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStream.cs +++ b/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStream.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -39,7 +40,7 @@ namespace System.IO /// </summary> public class UnmanagedMemoryStream : Stream { - private SafeBuffer _buffer; + private SafeBuffer? _buffer; private unsafe byte* _mem; private long _length; private long _capacity; @@ -47,7 +48,7 @@ namespace System.IO private long _offset; private FileAccess _access; private bool _isOpen; - private Task<int> _lastReadTask; // The last successful task returned from ReadAsync + private Task<int>? _lastReadTask; // The last successful task returned from ReadAsync /// <summary> /// Creates a closed stream. @@ -473,7 +474,7 @@ namespace System.IO try { int n = Read(buffer, offset, count); - Task<int> t = _lastReadTask; + Task<int>? t = _lastReadTask; return (t != null && t.Result == n) ? t : (_lastReadTask = Task.FromResult<Int32>(n)); } catch (Exception ex) diff --git a/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStreamWrapper.cs b/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStreamWrapper.cs index 9a598951ee..d4a5f98255 100644 --- a/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStreamWrapper.cs +++ b/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryStreamWrapper.cs @@ -11,9 +11,7 @@ ** ===========================================================*/ -using System; -using System.Runtime.InteropServices; -using System.Diagnostics.CodeAnalysis; +#nullable enable using System.Threading; using System.Threading.Tasks; diff --git a/src/System.Private.CoreLib/shared/System/IO/Win32Marshal.cs b/src/System.Private.CoreLib/shared/System/IO/Win32Marshal.cs index 7888d8d61b..bedebee683 100644 --- a/src/System.Private.CoreLib/shared/System/IO/Win32Marshal.cs +++ b/src/System.Private.CoreLib/shared/System/IO/Win32Marshal.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; namespace System.IO @@ -15,14 +16,14 @@ namespace System.IO /// Converts, resetting it, the last Win32 error into a corresponding <see cref="Exception"/> object, optionally /// including the specified path in the error message. /// </summary> - internal static Exception GetExceptionForLastWin32Error(string path = "") + internal static Exception GetExceptionForLastWin32Error(string? path = "") => GetExceptionForWin32Error(Marshal.GetLastWin32Error(), path); /// <summary> /// Converts the specified Win32 error into a corresponding <see cref="Exception"/> object, optionally /// including the specified path in the error message. /// </summary> - internal static Exception GetExceptionForWin32Error(int errorCode, string path = "") + internal static Exception GetExceptionForWin32Error(int errorCode, string? path = "") { switch (errorCode) { diff --git a/src/System.Private.CoreLib/shared/System/IndexOutOfRangeException.cs b/src/System.Private.CoreLib/shared/System/IndexOutOfRangeException.cs index aadc942314..46d8e3869e 100644 --- a/src/System.Private.CoreLib/shared/System/IndexOutOfRangeException.cs +++ b/src/System.Private.CoreLib/shared/System/IndexOutOfRangeException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -25,13 +26,13 @@ namespace System HResult = HResults.COR_E_INDEXOUTOFRANGE; } - public IndexOutOfRangeException(string message) + public IndexOutOfRangeException(string? message) : base(message) { HResult = HResults.COR_E_INDEXOUTOFRANGE; } - public IndexOutOfRangeException(string message, Exception innerException) + public IndexOutOfRangeException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_INDEXOUTOFRANGE; diff --git a/src/System.Private.CoreLib/shared/System/InsufficientExecutionStackException.cs b/src/System.Private.CoreLib/shared/System/InsufficientExecutionStackException.cs index 4c4bf242e1..e6b71b9ac2 100644 --- a/src/System.Private.CoreLib/shared/System/InsufficientExecutionStackException.cs +++ b/src/System.Private.CoreLib/shared/System/InsufficientExecutionStackException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System @@ -16,13 +17,13 @@ namespace System HResult = HResults.COR_E_INSUFFICIENTEXECUTIONSTACK; } - public InsufficientExecutionStackException(string message) + public InsufficientExecutionStackException(string? message) : base(message) { HResult = HResults.COR_E_INSUFFICIENTEXECUTIONSTACK; } - public InsufficientExecutionStackException(string message, Exception innerException) + public InsufficientExecutionStackException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_INSUFFICIENTEXECUTIONSTACK; diff --git a/src/System.Private.CoreLib/shared/System/InsufficientMemoryException.cs b/src/System.Private.CoreLib/shared/System/InsufficientMemoryException.cs index 68377540e6..197bd166d5 100644 --- a/src/System.Private.CoreLib/shared/System/InsufficientMemoryException.cs +++ b/src/System.Private.CoreLib/shared/System/InsufficientMemoryException.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +#nullable enable using System.Runtime.Serialization; namespace System @@ -30,13 +30,13 @@ namespace System HResult = HResults.COR_E_INSUFFICIENTMEMORY; } - public InsufficientMemoryException(string message) + public InsufficientMemoryException(string? message) : base(message) { HResult = HResults.COR_E_INSUFFICIENTMEMORY; } - public InsufficientMemoryException(string message, Exception innerException) + public InsufficientMemoryException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_INSUFFICIENTMEMORY; diff --git a/src/System.Private.CoreLib/shared/System/InvalidCastException.cs b/src/System.Private.CoreLib/shared/System/InvalidCastException.cs index cb6036aeb4..11c98ec05b 100644 --- a/src/System.Private.CoreLib/shared/System/InvalidCastException.cs +++ b/src/System.Private.CoreLib/shared/System/InvalidCastException.cs @@ -8,6 +8,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -22,19 +23,19 @@ namespace System HResult = HResults.COR_E_INVALIDCAST; } - public InvalidCastException(string message) + public InvalidCastException(string? message) : base(message) { HResult = HResults.COR_E_INVALIDCAST; } - public InvalidCastException(string message, Exception innerException) + public InvalidCastException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_INVALIDCAST; } - public InvalidCastException(string message, int errorCode) + public InvalidCastException(string? message, int errorCode) : base(message) { HResult = errorCode; diff --git a/src/System.Private.CoreLib/shared/System/InvalidOperationException.cs b/src/System.Private.CoreLib/shared/System/InvalidOperationException.cs index 9fffbec433..aec2b07b5e 100644 --- a/src/System.Private.CoreLib/shared/System/InvalidOperationException.cs +++ b/src/System.Private.CoreLib/shared/System/InvalidOperationException.cs @@ -12,6 +12,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -26,13 +27,13 @@ namespace System HResult = HResults.COR_E_INVALIDOPERATION; } - public InvalidOperationException(string message) + public InvalidOperationException(string? message) : base(message) { HResult = HResults.COR_E_INVALIDOPERATION; } - public InvalidOperationException(string message, Exception innerException) + public InvalidOperationException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_INVALIDOPERATION; diff --git a/src/System.Private.CoreLib/shared/System/InvalidProgramException.cs b/src/System.Private.CoreLib/shared/System/InvalidProgramException.cs index 62a14f9116..63f1bfee86 100644 --- a/src/System.Private.CoreLib/shared/System/InvalidProgramException.cs +++ b/src/System.Private.CoreLib/shared/System/InvalidProgramException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -25,13 +26,13 @@ namespace System HResult = HResults.COR_E_INVALIDPROGRAM; } - public InvalidProgramException(string message) + public InvalidProgramException(string? message) : base(message) { HResult = HResults.COR_E_INVALIDPROGRAM; } - public InvalidProgramException(string message, Exception inner) + public InvalidProgramException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_INVALIDPROGRAM; diff --git a/src/System.Private.CoreLib/shared/System/InvalidTimeZoneException.cs b/src/System.Private.CoreLib/shared/System/InvalidTimeZoneException.cs index 1bbb7e067b..cbf73c61ed 100644 --- a/src/System.Private.CoreLib/shared/System/InvalidTimeZoneException.cs +++ b/src/System.Private.CoreLib/shared/System/InvalidTimeZoneException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System @@ -14,12 +15,12 @@ namespace System { } - public InvalidTimeZoneException(string message) + public InvalidTimeZoneException(string? message) : base(message) { } - public InvalidTimeZoneException(string message, Exception innerException) + public InvalidTimeZoneException(string? message, Exception? innerException) : base(message, innerException) { } diff --git a/src/System.Private.CoreLib/shared/System/Lazy.cs b/src/System.Private.CoreLib/shared/System/Lazy.cs index ca445fc9d5..6b8c0a4835 100644 --- a/src/System.Private.CoreLib/shared/System/Lazy.cs +++ b/src/System.Private.CoreLib/shared/System/Lazy.cs @@ -10,9 +10,9 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System.Diagnostics; using System.Runtime.ExceptionServices; -using System.Runtime.InteropServices; using System.Threading; namespace System @@ -51,7 +51,7 @@ namespace System internal LazyState State { get; } - private readonly ExceptionDispatchInfo _exceptionDispatch; + private readonly ExceptionDispatchInfo? _exceptionDispatch; /// <summary> /// Constructor that defines the state @@ -121,14 +121,14 @@ namespace System } } - internal static LazyThreadSafetyMode? GetMode(LazyHelper state) + internal static LazyThreadSafetyMode? GetMode(LazyHelper? state) { if (state == null) return null; // we don't know the mode anymore return state.GetMode(); } - internal static bool GetIsValueFaulted(LazyHelper state) => state?._exceptionDispatch != null; + internal static bool GetIsValueFaulted(LazyHelper? state) => state?._exceptionDispatch != null; internal static LazyHelper Create(LazyThreadSafetyMode mode, bool useDefaultConstructor) { @@ -189,14 +189,14 @@ namespace System } // _state, a volatile reference, is set to null after _value has been set - private volatile LazyHelper _state; + private volatile LazyHelper? _state; // we ensure that _factory when finished is set to null to allow garbage collector to clean up // any referenced items - private Func<T> _factory; + private Func<T>? _factory; // _value eventually stores the lazily created value. It is valid when _state = null. - private T _value; + private T _value = default!; // TODO-NULLABLE-GENERIC /// <summary> /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/> class that @@ -206,7 +206,7 @@ namespace System /// An instance created with this constructor may be used concurrently from multiple threads. /// </remarks> public Lazy() - : this(null, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor:true) + : this(null, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor: true) { } @@ -237,7 +237,7 @@ namespace System /// An instance created with this constructor may be used concurrently from multiple threads. /// </remarks> public Lazy(Func<T> valueFactory) - : this(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor:false) + : this(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor: false) { } @@ -248,7 +248,7 @@ namespace System /// <param name="isThreadSafe">true if this instance should be usable by multiple threads concurrently; false if the instance will only be used by one thread at a time. /// </param> public Lazy(bool isThreadSafe) : - this(null, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor:true) + this(null, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor: true) { } @@ -275,7 +275,7 @@ namespace System /// <exception cref="System.ArgumentNullException"><paramref name="valueFactory"/> is /// a null reference (Nothing in Visual Basic).</exception> public Lazy(Func<T> valueFactory, bool isThreadSafe) : - this(valueFactory, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor:false) + this(valueFactory, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor: false) { } @@ -295,7 +295,7 @@ namespace System { } - private Lazy(Func<T> valueFactory, LazyThreadSafetyMode mode, bool useDefaultConstructor) + private Lazy(Func<T>? valueFactory, LazyThreadSafetyMode mode, bool useDefaultConstructor) { if (valueFactory == null && !useDefaultConstructor) throw new ArgumentNullException(nameof(valueFactory)); @@ -314,7 +314,7 @@ namespace System { try { - Func<T> factory = _factory; + Func<T>? factory = _factory; if (factory == null) throw new InvalidOperationException(SR.Lazy_Value_RecursiveCallsToValue); _factory = null; @@ -351,7 +351,7 @@ namespace System private void PublicationOnly(LazyHelper publicationOnly, T possibleValue) { - LazyHelper previous = Interlocked.CompareExchange(ref _state, LazyHelper.PublicationOnlyWaitForOtherThreadToPublish, publicationOnly); + LazyHelper? previous = Interlocked.CompareExchange(ref _state, LazyHelper.PublicationOnlyWaitForOtherThreadToPublish, publicationOnly); if (previous == publicationOnly) { _factory = null; @@ -367,7 +367,7 @@ namespace System private void PublicationOnlyViaFactory(LazyHelper initializer) { - Func<T> factory = _factory; + Func<T>? factory = _factory; if (factory == null) { PublicationOnlyWaitForOtherThreadToPublish(); @@ -393,7 +393,7 @@ namespace System { // we have to create a copy of state here, and use the copy exclusively from here on in // so as to ensure thread safety. - var state = _state; + LazyHelper? state = _state; if (state != null) { switch (state.State) @@ -440,9 +440,11 @@ namespace System /// <exception cref="T:System.NullReferenceException"> /// The <see cref="Value"/> is null. /// </exception> - public override string ToString() + public override string? ToString() { - return IsValueCreated ? Value.ToString() : SR.Lazy_ToString_ValueNotCreated; + return IsValueCreated ? + Value!.ToString() : // Throws NullReferenceException as if caller called ToString on the value itself + SR.Lazy_ToString_ValueNotCreated; } /// <summary>Gets the value of the Lazy<T> for debugging display purposes.</summary> @@ -452,7 +454,7 @@ namespace System { if (!IsValueCreated) { - return default; + return default!; // TODO-NULLABLE-GENERIC } return _value; } @@ -527,8 +529,7 @@ namespace System /// <summary>Returns the value of the Lazy object.</summary> public T Value { - get - { return _lazy.ValueForDebugDisplay; } + get { return _lazy.ValueForDebugDisplay; } } /// <summary>Returns the execution mode of the Lazy object</summary> diff --git a/src/System.Private.CoreLib/shared/System/MemberAccessException.cs b/src/System.Private.CoreLib/shared/System/MemberAccessException.cs index 0cf1e0fbeb..5d771ba848 100644 --- a/src/System.Private.CoreLib/shared/System/MemberAccessException.cs +++ b/src/System.Private.CoreLib/shared/System/MemberAccessException.cs @@ -8,6 +8,7 @@ // access, due to it being removed, private or something similar. //////////////////////////////////////////////////////////////////////////////// +#nullable enable using System.Runtime.Serialization; namespace System @@ -31,13 +32,13 @@ namespace System // message, its HRESULT set to COR_E_ACCESS, // and its ExceptionInfo reference set to null. // - public MemberAccessException(string message) + public MemberAccessException(string? message) : base(message) { HResult = HResults.COR_E_MEMBERACCESS; } - public MemberAccessException(string message, Exception inner) + public MemberAccessException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_MEMBERACCESS; diff --git a/src/System.Private.CoreLib/shared/System/MethodAccessException.cs b/src/System.Private.CoreLib/shared/System/MethodAccessException.cs index f329334b23..23625490f9 100644 --- a/src/System.Private.CoreLib/shared/System/MethodAccessException.cs +++ b/src/System.Private.CoreLib/shared/System/MethodAccessException.cs @@ -9,6 +9,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -23,13 +24,13 @@ namespace System HResult = HResults.COR_E_METHODACCESS; } - public MethodAccessException(string message) + public MethodAccessException(string? message) : base(message) { HResult = HResults.COR_E_METHODACCESS; } - public MethodAccessException(string message, Exception inner) + public MethodAccessException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_METHODACCESS; diff --git a/src/System.Private.CoreLib/shared/System/MissingFieldException.cs b/src/System.Private.CoreLib/shared/System/MissingFieldException.cs index ba66bed0cd..be41b3592c 100644 --- a/src/System.Private.CoreLib/shared/System/MissingFieldException.cs +++ b/src/System.Private.CoreLib/shared/System/MissingFieldException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System @@ -16,19 +17,19 @@ namespace System HResult = HResults.COR_E_MISSINGFIELD; } - public MissingFieldException(string message) + public MissingFieldException(string? message) : base(message) { HResult = HResults.COR_E_MISSINGFIELD; } - public MissingFieldException(string message, Exception inner) + public MissingFieldException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_MISSINGFIELD; } - public MissingFieldException(string className, string fieldName) + public MissingFieldException(string? className, string? fieldName) { ClassName = className; MemberName = fieldName; diff --git a/src/System.Private.CoreLib/shared/System/MissingMemberException.cs b/src/System.Private.CoreLib/shared/System/MissingMemberException.cs index a3da06017b..e04a468c8f 100644 --- a/src/System.Private.CoreLib/shared/System/MissingMemberException.cs +++ b/src/System.Private.CoreLib/shared/System/MissingMemberException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System @@ -16,19 +17,19 @@ namespace System HResult = HResults.COR_E_MISSINGMEMBER; } - public MissingMemberException(string message) + public MissingMemberException(string? message) : base(message) { HResult = HResults.COR_E_MISSINGMEMBER; } - public MissingMemberException(string message, Exception inner) + public MissingMemberException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_MISSINGMEMBER; } - public MissingMemberException(string className, string memberName) + public MissingMemberException(string? className, string? memberName) { ClassName = className; MemberName = memberName; @@ -69,8 +70,8 @@ namespace System // If ClassName != null, GetMessage will construct on the fly using it // and the other variables. This allows customization of the // format depending on the language environment. - protected string ClassName; - protected string MemberName; - protected byte[] Signature; + protected string? ClassName; + protected string? MemberName; + protected byte[]? Signature; } } diff --git a/src/System.Private.CoreLib/shared/System/MissingMethodException.cs b/src/System.Private.CoreLib/shared/System/MissingMethodException.cs index abb6c0e97b..8a94ac5696 100644 --- a/src/System.Private.CoreLib/shared/System/MissingMethodException.cs +++ b/src/System.Private.CoreLib/shared/System/MissingMethodException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -25,19 +26,19 @@ namespace System HResult = HResults.COR_E_MISSINGMETHOD; } - public MissingMethodException(string message) + public MissingMethodException(string? message) : base(message) { HResult = HResults.COR_E_MISSINGMETHOD; } - public MissingMethodException(string message, Exception inner) + public MissingMethodException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_MISSINGMETHOD; } - public MissingMethodException(string className, string methodName) + public MissingMethodException(string? className, string? methodName) { ClassName = className; MemberName = methodName; diff --git a/src/System.Private.CoreLib/shared/System/MulticastNotSupportedException.cs b/src/System.Private.CoreLib/shared/System/MulticastNotSupportedException.cs index cb07ac7d09..912e569b26 100644 --- a/src/System.Private.CoreLib/shared/System/MulticastNotSupportedException.cs +++ b/src/System.Private.CoreLib/shared/System/MulticastNotSupportedException.cs @@ -7,6 +7,7 @@ // This is thrown when you add multiple callbacks to a non-multicast delegate. //////////////////////////////////////////////////////////////////////////////// +#nullable enable using System.Runtime.Serialization; namespace System @@ -21,13 +22,13 @@ namespace System HResult = HResults.COR_E_MULTICASTNOTSUPPORTED; } - public MulticastNotSupportedException(string message) + public MulticastNotSupportedException(string? message) : base(message) { HResult = HResults.COR_E_MULTICASTNOTSUPPORTED; } - public MulticastNotSupportedException(string message, Exception inner) + public MulticastNotSupportedException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_MULTICASTNOTSUPPORTED; diff --git a/src/System.Private.CoreLib/shared/System/NotFiniteNumberException.cs b/src/System.Private.CoreLib/shared/System/NotFiniteNumberException.cs index 9afc104588..af464124eb 100644 --- a/src/System.Private.CoreLib/shared/System/NotFiniteNumberException.cs +++ b/src/System.Private.CoreLib/shared/System/NotFiniteNumberException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System @@ -26,27 +27,27 @@ namespace System HResult = HResults.COR_E_NOTFINITENUMBER; } - public NotFiniteNumberException(string message) + public NotFiniteNumberException(string? message) : base(message) { _offendingNumber = 0; HResult = HResults.COR_E_NOTFINITENUMBER; } - public NotFiniteNumberException(string message, double offendingNumber) + public NotFiniteNumberException(string? message, double offendingNumber) : base(message) { _offendingNumber = offendingNumber; HResult = HResults.COR_E_NOTFINITENUMBER; } - public NotFiniteNumberException(string message, Exception innerException) + public NotFiniteNumberException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_NOTFINITENUMBER; } - public NotFiniteNumberException(string message, double offendingNumber, Exception innerException) + public NotFiniteNumberException(string? message, double offendingNumber, Exception? innerException) : base(message, innerException) { _offendingNumber = offendingNumber; diff --git a/src/System.Private.CoreLib/shared/System/NotImplementedException.cs b/src/System.Private.CoreLib/shared/System/NotImplementedException.cs index e5f378fed3..42d207459b 100644 --- a/src/System.Private.CoreLib/shared/System/NotImplementedException.cs +++ b/src/System.Private.CoreLib/shared/System/NotImplementedException.cs @@ -12,6 +12,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -25,12 +26,12 @@ namespace System { HResult = HResults.E_NOTIMPL; } - public NotImplementedException(string message) + public NotImplementedException(string? message) : base(message) { HResult = HResults.E_NOTIMPL; } - public NotImplementedException(string message, Exception inner) + public NotImplementedException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.E_NOTIMPL; diff --git a/src/System.Private.CoreLib/shared/System/NotSupportedException.cs b/src/System.Private.CoreLib/shared/System/NotSupportedException.cs index e3191ea13e..2fabb8ea06 100644 --- a/src/System.Private.CoreLib/shared/System/NotSupportedException.cs +++ b/src/System.Private.CoreLib/shared/System/NotSupportedException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -25,13 +26,13 @@ namespace System HResult = HResults.COR_E_NOTSUPPORTED; } - public NotSupportedException(string message) + public NotSupportedException(string? message) : base(message) { HResult = HResults.COR_E_NOTSUPPORTED; } - public NotSupportedException(string message, Exception innerException) + public NotSupportedException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_NOTSUPPORTED; diff --git a/src/System.Private.CoreLib/shared/System/NullReferenceException.cs b/src/System.Private.CoreLib/shared/System/NullReferenceException.cs index cfbc0fb78e..f95a7699dd 100644 --- a/src/System.Private.CoreLib/shared/System/NullReferenceException.cs +++ b/src/System.Private.CoreLib/shared/System/NullReferenceException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -25,13 +26,13 @@ namespace System HResult = HResults.COR_E_NULLREFERENCE; } - public NullReferenceException(string message) + public NullReferenceException(string? message) : base(message) { HResult = HResults.COR_E_NULLREFERENCE; } - public NullReferenceException(string message, Exception innerException) + public NullReferenceException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_NULLREFERENCE; diff --git a/src/System.Private.CoreLib/shared/System/Object.cs b/src/System.Private.CoreLib/shared/System/Object.cs index 10af793ca6..2bdb5c545a 100644 --- a/src/System.Private.CoreLib/shared/System/Object.cs +++ b/src/System.Private.CoreLib/shared/System/Object.cs @@ -36,7 +36,7 @@ namespace System // Returns a String which represents the object instance. The default // for an object is to return the fully qualified name of the class. - public virtual string ToString() + public virtual string? ToString() { return GetType().ToString(); } diff --git a/src/System.Private.CoreLib/shared/System/ObjectDisposedException.cs b/src/System.Private.CoreLib/shared/System/ObjectDisposedException.cs index 8f13055b94..d5d488447f 100644 --- a/src/System.Private.CoreLib/shared/System/ObjectDisposedException.cs +++ b/src/System.Private.CoreLib/shared/System/ObjectDisposedException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Globalization; using System.Runtime.Serialization; @@ -15,7 +16,7 @@ namespace System [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class ObjectDisposedException : InvalidOperationException { - private string _objectName; + private string? _objectName; // This constructor should only be called by the EE (COMPlusThrow) private ObjectDisposedException() : @@ -23,18 +24,18 @@ namespace System { } - public ObjectDisposedException(string objectName) : + public ObjectDisposedException(string? objectName) : this(objectName, SR.ObjectDisposed_Generic) { } - public ObjectDisposedException(string objectName, string message) : base(message) + public ObjectDisposedException(string? objectName, string? message) : base(message) { HResult = HResults.COR_E_OBJECTDISPOSED; _objectName = objectName; } - public ObjectDisposedException(string message, Exception innerException) + public ObjectDisposedException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_OBJECTDISPOSED; @@ -60,7 +61,7 @@ namespace System get { string name = ObjectName; - if (name == null || name.Length == 0) + if (string.IsNullOrEmpty(name)) return base.Message; string objectDisposed = SR.Format(SR.ObjectDisposed_ObjectName_Name, name); @@ -68,16 +69,6 @@ namespace System } } - public string ObjectName - { - get - { - if (_objectName == null) - { - return string.Empty; - } - return _objectName; - } - } + public string ObjectName => _objectName ?? string.Empty; } } diff --git a/src/System.Private.CoreLib/shared/System/OperationCanceledException.cs b/src/System.Private.CoreLib/shared/System/OperationCanceledException.cs index 0c311afd7d..029024603e 100644 --- a/src/System.Private.CoreLib/shared/System/OperationCanceledException.cs +++ b/src/System.Private.CoreLib/shared/System/OperationCanceledException.cs @@ -11,6 +11,7 @@ ** ===========================================================*/ +#nullable enable using System; using System.Runtime.Serialization; using System.Threading; @@ -36,13 +37,13 @@ namespace System HResult = HResults.COR_E_OPERATIONCANCELED; } - public OperationCanceledException(string message) + public OperationCanceledException(string? message) : base(message) { HResult = HResults.COR_E_OPERATIONCANCELED; } - public OperationCanceledException(string message, Exception innerException) + public OperationCanceledException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_OPERATIONCANCELED; @@ -55,13 +56,13 @@ namespace System CancellationToken = token; } - public OperationCanceledException(string message, CancellationToken token) + public OperationCanceledException(string? message, CancellationToken token) : this(message) { CancellationToken = token; } - public OperationCanceledException(string message, Exception innerException, CancellationToken token) + public OperationCanceledException(string? message, Exception? innerException, CancellationToken token) : this(message, innerException) { CancellationToken = token; diff --git a/src/System.Private.CoreLib/shared/System/OutOfMemoryException.cs b/src/System.Private.CoreLib/shared/System/OutOfMemoryException.cs index 194f3bfdad..336618c2a0 100644 --- a/src/System.Private.CoreLib/shared/System/OutOfMemoryException.cs +++ b/src/System.Private.CoreLib/shared/System/OutOfMemoryException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System @@ -24,13 +25,13 @@ namespace System HResult = HResults.COR_E_OUTOFMEMORY; } - public OutOfMemoryException(string message) + public OutOfMemoryException(string? message) : base(message) { HResult = HResults.COR_E_OUTOFMEMORY; } - public OutOfMemoryException(string message, Exception innerException) + public OutOfMemoryException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_OUTOFMEMORY; diff --git a/src/System.Private.CoreLib/shared/System/OverflowException.cs b/src/System.Private.CoreLib/shared/System/OverflowException.cs index c18fe3f7b3..172ecf0f6c 100644 --- a/src/System.Private.CoreLib/shared/System/OverflowException.cs +++ b/src/System.Private.CoreLib/shared/System/OverflowException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -25,13 +26,13 @@ namespace System HResult = HResults.COR_E_OVERFLOW; } - public OverflowException(string message) + public OverflowException(string? message) : base(message) { HResult = HResults.COR_E_OVERFLOW; } - public OverflowException(string message, Exception innerException) + public OverflowException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_OVERFLOW; diff --git a/src/System.Private.CoreLib/shared/System/PlatformNotSupportedException.cs b/src/System.Private.CoreLib/shared/System/PlatformNotSupportedException.cs index f9e461ed0a..ee953ce16b 100644 --- a/src/System.Private.CoreLib/shared/System/PlatformNotSupportedException.cs +++ b/src/System.Private.CoreLib/shared/System/PlatformNotSupportedException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -25,13 +26,13 @@ namespace System HResult = HResults.COR_E_PLATFORMNOTSUPPORTED; } - public PlatformNotSupportedException(string message) + public PlatformNotSupportedException(string? message) : base(message) { HResult = HResults.COR_E_PLATFORMNOTSUPPORTED; } - public PlatformNotSupportedException(string message, Exception inner) + public PlatformNotSupportedException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_PLATFORMNOTSUPPORTED; diff --git a/src/System.Private.CoreLib/shared/System/RankException.cs b/src/System.Private.CoreLib/shared/System/RankException.cs index e1e7d169b8..135a6c9d46 100644 --- a/src/System.Private.CoreLib/shared/System/RankException.cs +++ b/src/System.Private.CoreLib/shared/System/RankException.cs @@ -12,6 +12,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -26,13 +27,13 @@ namespace System HResult = HResults.COR_E_RANK; } - public RankException(string message) + public RankException(string? message) : base(message) { HResult = HResults.COR_E_RANK; } - public RankException(string message, Exception innerException) + public RankException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_RANK; diff --git a/src/System.Private.CoreLib/shared/System/Reflection/AmbiguousMatchException.cs b/src/System.Private.CoreLib/shared/System/Reflection/AmbiguousMatchException.cs index 643a127c49..aa321e99f1 100644 --- a/src/System.Private.CoreLib/shared/System/Reflection/AmbiguousMatchException.cs +++ b/src/System.Private.CoreLib/shared/System/Reflection/AmbiguousMatchException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Reflection @@ -16,13 +17,13 @@ namespace System.Reflection HResult = HResults.COR_E_AMBIGUOUSMATCH; } - public AmbiguousMatchException(string message) + public AmbiguousMatchException(string? message) : base(message) { HResult = HResults.COR_E_AMBIGUOUSMATCH; } - public AmbiguousMatchException(string message, Exception inner) + public AmbiguousMatchException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_AMBIGUOUSMATCH; diff --git a/src/System.Private.CoreLib/shared/System/Reflection/CustomAttributeFormatException.cs b/src/System.Private.CoreLib/shared/System/Reflection/CustomAttributeFormatException.cs index 1d7d4a7671..0d38eaaebc 100644 --- a/src/System.Private.CoreLib/shared/System/Reflection/CustomAttributeFormatException.cs +++ b/src/System.Private.CoreLib/shared/System/Reflection/CustomAttributeFormatException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Reflection @@ -15,12 +16,12 @@ namespace System.Reflection { } - public CustomAttributeFormatException(string message) + public CustomAttributeFormatException(string? message) : this(message, null) { } - public CustomAttributeFormatException(string message, Exception inner) + public CustomAttributeFormatException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_CUSTOMATTRIBUTEFORMAT; diff --git a/src/System.Private.CoreLib/shared/System/Reflection/InvalidFilterCriteriaException.cs b/src/System.Private.CoreLib/shared/System/Reflection/InvalidFilterCriteriaException.cs index dedcc54f4c..e6e6468b1b 100644 --- a/src/System.Private.CoreLib/shared/System/Reflection/InvalidFilterCriteriaException.cs +++ b/src/System.Private.CoreLib/shared/System/Reflection/InvalidFilterCriteriaException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Reflection @@ -15,12 +16,12 @@ namespace System.Reflection { } - public InvalidFilterCriteriaException(string message) + public InvalidFilterCriteriaException(string? message) : this(message, null) { } - public InvalidFilterCriteriaException(string message, Exception inner) + public InvalidFilterCriteriaException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_INVALIDFILTERCRITERIA; diff --git a/src/System.Private.CoreLib/shared/System/Reflection/ReflectionTypeLoadException.cs b/src/System.Private.CoreLib/shared/System/Reflection/ReflectionTypeLoadException.cs index 5011c50053..ff2d85a83a 100644 --- a/src/System.Private.CoreLib/shared/System/Reflection/ReflectionTypeLoadException.cs +++ b/src/System.Private.CoreLib/shared/System/Reflection/ReflectionTypeLoadException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; using System.Text; @@ -11,7 +12,7 @@ namespace System.Reflection [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public sealed class ReflectionTypeLoadException : SystemException, ISerializable { - public ReflectionTypeLoadException(Type[] classes, Exception[] exceptions) + public ReflectionTypeLoadException(Type[]? classes, Exception?[]? exceptions) : base(null) { Types = classes; @@ -19,7 +20,7 @@ namespace System.Reflection HResult = HResults.COR_E_REFLECTIONTYPELOAD; } - public ReflectionTypeLoadException(Type[] classes, Exception[] exceptions, string message) + public ReflectionTypeLoadException(Type[]? classes, Exception?[]? exceptions, string? message) : base(message) { Types = classes; @@ -40,9 +41,9 @@ namespace System.Reflection info.AddValue("Exceptions", LoaderExceptions, typeof(Exception[])); } - public Type[] Types { get; } + public Type[]? Types { get; } - public Exception[] LoaderExceptions { get; } + public Exception?[]? LoaderExceptions { get; } public override string Message => CreateString(isMessage: true); @@ -52,14 +53,14 @@ namespace System.Reflection { string baseValue = isMessage ? base.Message : base.ToString(); - Exception[] exceptions = LoaderExceptions; + Exception?[]? exceptions = LoaderExceptions; if (exceptions == null || exceptions.Length == 0) { return baseValue; } var text = new StringBuilder(baseValue); - foreach (Exception e in exceptions) + foreach (Exception? e in exceptions) { if (e != null) { diff --git a/src/System.Private.CoreLib/shared/System/Reflection/TargetException.cs b/src/System.Private.CoreLib/shared/System/Reflection/TargetException.cs index c200000738..7a1b90a5f1 100644 --- a/src/System.Private.CoreLib/shared/System/Reflection/TargetException.cs +++ b/src/System.Private.CoreLib/shared/System/Reflection/TargetException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Reflection @@ -15,12 +16,12 @@ namespace System.Reflection { } - public TargetException(string message) + public TargetException(string? message) : this(message, null) { } - public TargetException(string message, Exception inner) + public TargetException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_TARGET; diff --git a/src/System.Private.CoreLib/shared/System/Reflection/TargetInvocationException.cs b/src/System.Private.CoreLib/shared/System/Reflection/TargetInvocationException.cs index 822ddfdfb2..61312f28ed 100644 --- a/src/System.Private.CoreLib/shared/System/Reflection/TargetInvocationException.cs +++ b/src/System.Private.CoreLib/shared/System/Reflection/TargetInvocationException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Reflection @@ -10,13 +11,13 @@ namespace System.Reflection [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public sealed class TargetInvocationException : ApplicationException { - public TargetInvocationException(Exception inner) + public TargetInvocationException(Exception? inner) : base(SR.Arg_TargetInvocationException, inner) { HResult = HResults.COR_E_TARGETINVOCATION; } - public TargetInvocationException(string message, Exception inner) + public TargetInvocationException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_TARGETINVOCATION; diff --git a/src/System.Private.CoreLib/shared/System/Reflection/TargetParameterCountException.cs b/src/System.Private.CoreLib/shared/System/Reflection/TargetParameterCountException.cs index c68c467290..72b667ed46 100644 --- a/src/System.Private.CoreLib/shared/System/Reflection/TargetParameterCountException.cs +++ b/src/System.Private.CoreLib/shared/System/Reflection/TargetParameterCountException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Reflection @@ -16,13 +17,13 @@ namespace System.Reflection HResult = HResults.COR_E_TARGETPARAMCOUNT; } - public TargetParameterCountException(string message) + public TargetParameterCountException(string? message) : base(message) { HResult = HResults.COR_E_TARGETPARAMCOUNT; } - public TargetParameterCountException(string message, Exception inner) + public TargetParameterCountException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_TARGETPARAMCOUNT; diff --git a/src/System.Private.CoreLib/shared/System/Resources/MissingManifestResourceException.cs b/src/System.Private.CoreLib/shared/System/Resources/MissingManifestResourceException.cs index 20914ac7e1..6f14991249 100644 --- a/src/System.Private.CoreLib/shared/System/Resources/MissingManifestResourceException.cs +++ b/src/System.Private.CoreLib/shared/System/Resources/MissingManifestResourceException.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +#nullable enable using System.Runtime.Serialization; namespace System.Resources @@ -17,13 +17,13 @@ namespace System.Resources HResult = System.HResults.COR_E_MISSINGMANIFESTRESOURCE; } - public MissingManifestResourceException(string message) + public MissingManifestResourceException(string? message) : base(message) { HResult = System.HResults.COR_E_MISSINGMANIFESTRESOURCE; } - public MissingManifestResourceException(string message, Exception inner) + public MissingManifestResourceException(string? message, Exception? inner) : base(message, inner) { HResult = System.HResults.COR_E_MISSINGMANIFESTRESOURCE; diff --git a/src/System.Private.CoreLib/shared/System/Resources/MissingSatelliteAssemblyException.cs b/src/System.Private.CoreLib/shared/System/Resources/MissingSatelliteAssemblyException.cs index 0bbc626734..a403379c36 100644 --- a/src/System.Private.CoreLib/shared/System/Resources/MissingSatelliteAssemblyException.cs +++ b/src/System.Private.CoreLib/shared/System/Resources/MissingSatelliteAssemblyException.cs @@ -15,7 +15,7 @@ ** ===========================================================*/ -using System; +#nullable enable using System.Runtime.Serialization; namespace System.Resources @@ -24,7 +24,7 @@ namespace System.Resources [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class MissingSatelliteAssemblyException : SystemException { - private string _cultureName; + private string? _cultureName; public MissingSatelliteAssemblyException() : base(SR.MissingSatelliteAssembly_Default) @@ -32,20 +32,20 @@ namespace System.Resources HResult = System.HResults.COR_E_MISSINGSATELLITEASSEMBLY; } - public MissingSatelliteAssemblyException(string message) + public MissingSatelliteAssemblyException(string? message) : base(message) { HResult = System.HResults.COR_E_MISSINGSATELLITEASSEMBLY; } - public MissingSatelliteAssemblyException(string message, string cultureName) + public MissingSatelliteAssemblyException(string? message, string? cultureName) : base(message) { HResult = System.HResults.COR_E_MISSINGSATELLITEASSEMBLY; _cultureName = cultureName; } - public MissingSatelliteAssemblyException(string message, Exception inner) + public MissingSatelliteAssemblyException(string? message, Exception? inner) : base(message, inner) { HResult = System.HResults.COR_E_MISSINGSATELLITEASSEMBLY; @@ -56,9 +56,6 @@ namespace System.Resources { } - public string CultureName - { - get { return _cultureName; } - } + public string? CultureName => _cultureName; } } diff --git a/src/System.Private.CoreLib/shared/System/Runtime/AmbiguousImplementationException.cs b/src/System.Private.CoreLib/shared/System/Runtime/AmbiguousImplementationException.cs index 9e43ec0196..401a8fcb0e 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/AmbiguousImplementationException.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/AmbiguousImplementationException.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Globalization; +#nullable enable using System.Runtime.Serialization; namespace System.Runtime @@ -17,13 +17,13 @@ namespace System.Runtime HResult = HResults.COR_E_AMBIGUOUSIMPLEMENTATION; } - public AmbiguousImplementationException(string message) + public AmbiguousImplementationException(string? message) : base(message) { HResult = HResults.COR_E_AMBIGUOUSIMPLEMENTATION; } - public AmbiguousImplementationException(string message, Exception innerException) + public AmbiguousImplementationException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_AMBIGUOUSIMPLEMENTATION; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeWrappedException.cs b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeWrappedException.cs index 72996c6dfc..6af2b280b3 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeWrappedException.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeWrappedException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Runtime.CompilerServices diff --git a/src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs b/src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs index 3578d43d9c..57cbcf78c6 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Runtime.ExceptionServices diff --git a/src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionNotification.cs b/src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionNotification.cs index 605588d657..9357e2fa5a 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionNotification.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/ExceptionServices/ExceptionNotification.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Runtime.ExceptionServices { // Definition of the argument-type passed to the FirstChanceException event handler diff --git a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/COMException.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/COMException.cs index 0823c5670c..cc51358add 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/COMException.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/COMException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; using System.Globalization; using System.Text; @@ -23,19 +24,19 @@ namespace System.Runtime.InteropServices HResult = HResults.E_FAIL; } - public COMException(string message) + public COMException(string? message) : base(message) { HResult = HResults.E_FAIL; } - public COMException(string message, Exception inner) + public COMException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.E_FAIL; } - public COMException(string message, int errorCode) + public COMException(string? message, int errorCode) : base(message) { HResult = errorCode; @@ -58,13 +59,13 @@ namespace System.Runtime.InteropServices s.Append(": ").Append(message); } - Exception innerException = InnerException; + Exception? innerException = InnerException; if (innerException != null) { s.Append(" ---> ").Append(innerException.ToString()); } - string stackTrace = StackTrace; + string? stackTrace = StackTrace; if (stackTrace != null) s.Append(Environment.NewLine).Append(stackTrace); diff --git a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ExternalException.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ExternalException.cs index ab5a84c08a..0ac83759de 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ExternalException.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/ExternalException.cs @@ -12,7 +12,7 @@ ** =============================================================================*/ -using System; +#nullable enable using System.Globalization; using System.Runtime.Serialization; @@ -30,19 +30,19 @@ namespace System.Runtime.InteropServices HResult = HResults.E_FAIL; } - public ExternalException(string message) + public ExternalException(string? message) : base(message) { HResult = HResults.E_FAIL; } - public ExternalException(string message, Exception inner) + public ExternalException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.E_FAIL; } - public ExternalException(string message, int errorCode) + public ExternalException(string? message, int errorCode) : base(message) { HResult = errorCode; @@ -68,13 +68,12 @@ namespace System.Runtime.InteropServices string s = className + " (0x" + HResult.ToString("X8", CultureInfo.InvariantCulture) + ")"; - if (!(string.IsNullOrEmpty(message))) + if (!string.IsNullOrEmpty(message)) { s = s + ": " + message; } - Exception innerException = InnerException; - + Exception? innerException = InnerException; if (innerException != null) { s = s + " ---> " + innerException.ToString(); diff --git a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/InvalidComObjectException.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/InvalidComObjectException.cs index 3b00be1318..c2820f48ce 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/InvalidComObjectException.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/InvalidComObjectException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Runtime.InteropServices @@ -21,13 +22,13 @@ namespace System.Runtime.InteropServices HResult = HResults.COR_E_INVALIDCOMOBJECT; } - public InvalidComObjectException(string message) + public InvalidComObjectException(string? message) : base(message) { HResult = HResults.COR_E_INVALIDCOMOBJECT; } - public InvalidComObjectException(string message, Exception inner) + public InvalidComObjectException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_INVALIDCOMOBJECT; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/InvalidOleVariantTypeException.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/InvalidOleVariantTypeException.cs index 48b1ac3b04..cde7b5d218 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/InvalidOleVariantTypeException.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/InvalidOleVariantTypeException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Runtime.InteropServices @@ -20,13 +21,13 @@ namespace System.Runtime.InteropServices HResult = HResults.COR_E_INVALIDOLEVARIANTTYPE; } - public InvalidOleVariantTypeException(string message) + public InvalidOleVariantTypeException(string? message) : base(message) { HResult = HResults.COR_E_INVALIDOLEVARIANTTYPE; } - public InvalidOleVariantTypeException(string message, Exception inner) + public InvalidOleVariantTypeException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_INVALIDOLEVARIANTTYPE; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/MarshalDirectiveException.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/MarshalDirectiveException.cs index 3bb1140f5e..b827ee3344 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/MarshalDirectiveException.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/MarshalDirectiveException.cs @@ -11,8 +11,7 @@ ** =============================================================================*/ - -using System; +#nullable enable using System.Runtime.Serialization; namespace System.Runtime.InteropServices @@ -27,13 +26,13 @@ namespace System.Runtime.InteropServices HResult = HResults.COR_E_MARSHALDIRECTIVE; } - public MarshalDirectiveException(string message) + public MarshalDirectiveException(string? message) : base(message) { HResult = HResults.COR_E_MARSHALDIRECTIVE; } - public MarshalDirectiveException(string message, Exception inner) + public MarshalDirectiveException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_MARSHALDIRECTIVE; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/SEHException.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/SEHException.cs index 85e900b3ca..dd7b615db2 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/SEHException.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/SEHException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Runtime.InteropServices @@ -19,13 +20,13 @@ namespace System.Runtime.InteropServices HResult = HResults.E_FAIL; } - public SEHException(string message) + public SEHException(string? message) : base(message) { HResult = HResults.E_FAIL; } - public SEHException(string message, Exception inner) + public SEHException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.E_FAIL; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/SafeArrayRankMismatchException.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/SafeArrayRankMismatchException.cs index 5df2ed484c..98e4dcb2bf 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/SafeArrayRankMismatchException.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/SafeArrayRankMismatchException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Runtime.InteropServices @@ -20,13 +21,13 @@ namespace System.Runtime.InteropServices HResult = HResults.COR_E_SAFEARRAYRANKMISMATCH; } - public SafeArrayRankMismatchException(string message) + public SafeArrayRankMismatchException(string? message) : base(message) { HResult = HResults.COR_E_SAFEARRAYRANKMISMATCH; } - public SafeArrayRankMismatchException(string message, Exception inner) + public SafeArrayRankMismatchException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_SAFEARRAYRANKMISMATCH; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/SafeArrayTypeMismatchException.cs b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/SafeArrayTypeMismatchException.cs index d1e787c4f8..58bb3f87bb 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/SafeArrayTypeMismatchException.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/SafeArrayTypeMismatchException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Runtime.InteropServices @@ -20,13 +21,13 @@ namespace System.Runtime.InteropServices HResult = HResults.COR_E_SAFEARRAYTYPEMISMATCH; } - public SafeArrayTypeMismatchException(string message) + public SafeArrayTypeMismatchException(string? message) : base(message) { HResult = HResults.COR_E_SAFEARRAYTYPEMISMATCH; } - public SafeArrayTypeMismatchException(string message, Exception inner) + public SafeArrayTypeMismatchException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_SAFEARRAYTYPEMISMATCH; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Aes.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Aes.PlatformNotSupported.cs index 1f19ecea9e..ba9c310a63 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Aes.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Aes.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Aes.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Aes.cs index c4f2dc078f..02829e4f99 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Aes.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Aes.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Base.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Base.PlatformNotSupported.cs index 95c32527af..a74e23829f 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Base.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Base.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Base.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Base.cs index c993c411d5..3361fbe96f 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Base.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Base.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha1.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha1.PlatformNotSupported.cs index 970a4da3e1..16a73c6393 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha1.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha1.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha1.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha1.cs index a6c1901142..0c738e0247 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha1.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha1.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha256.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha256.PlatformNotSupported.cs index 7cb6fd7f3b..f56cfa4597 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha256.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha256.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha256.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha256.cs index 4b4b16dff5..23007b405d 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha256.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Sha256.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Simd.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Simd.PlatformNotSupported.cs index 9beb3aa2b7..cefa1ed37c 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Simd.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Simd.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Simd.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Simd.cs index c71daf162d..136ea1c715 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Simd.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Arm/Arm64/Simd.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128.cs index 4c3232693d..70083395e6 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.Intrinsics.X86; using Internal.Runtime.CompilerServices; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128DebugView_1.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128DebugView_1.cs index ccdc655949..7d5968bd4d 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128DebugView_1.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128DebugView_1.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Internal.Runtime.CompilerServices; namespace System.Runtime.Intrinsics diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128_1.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128_1.cs index 6598a573ce..7f837c7fe4 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128_1.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector128_1.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; @@ -145,7 +146,7 @@ namespace System.Runtime.Intrinsics /// <param name="obj">The object to compare with the current instance.</param> /// <returns><c>true</c> if <paramref name="obj" /> is a <see cref="Vector128{T}" /> and is equal to the current instance; otherwise, <c>false</c>.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> - public override bool Equals(object obj) + public override bool Equals(object? obj) { return (obj is Vector128<T>) && Equals((Vector128<T>)(obj)); } @@ -179,7 +180,7 @@ namespace System.Runtime.Intrinsics /// <param name="format">The format specifier used to format the individual elements of the current instance.</param> /// <returns>An equivalent string representation of the current instance.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> - public string ToString(string format) + public string ToString(string? format) { return ToString(format, formatProvider: null); } @@ -189,7 +190,7 @@ namespace System.Runtime.Intrinsics /// <param name="formatProvider">The format provider used to format the individual elements of the current instance.</param> /// <returns>An equivalent string representation of the current instance.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> - public string ToString(string format, IFormatProvider formatProvider) + public string ToString(string? format, IFormatProvider? formatProvider) { ThrowHelper.ThrowForUnsupportedVectorBaseType<T>(); diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256.cs index adf8207bab..116b93a73d 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.Intrinsics.X86; using Internal.Runtime.CompilerServices; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256DebugView_1.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256DebugView_1.cs index 5131341ad8..488d6d2a88 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256DebugView_1.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256DebugView_1.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Internal.Runtime.CompilerServices; namespace System.Runtime.Intrinsics diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256_1.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256_1.cs index 07ba97163e..903d2cd941 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256_1.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector256_1.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; @@ -146,7 +147,7 @@ namespace System.Runtime.Intrinsics /// <param name="obj">The object to compare with the current instance.</param> /// <returns><c>true</c> if <paramref name="obj" /> is a <see cref="Vector256{T}" /> and is equal to the current instance; otherwise, <c>false</c>.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> - public override bool Equals(object obj) + public override bool Equals(object? obj) { return (obj is Vector256<T>) && Equals((Vector256<T>)(obj)); } @@ -180,7 +181,7 @@ namespace System.Runtime.Intrinsics /// <param name="format">The format specifier used to format the individual elements of the current instance.</param> /// <returns>An equivalent string representation of the current instance.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> - public string ToString(string format) + public string ToString(string? format) { return ToString(format, formatProvider: null); } @@ -190,7 +191,7 @@ namespace System.Runtime.Intrinsics /// <param name="formatProvider">The format provider used to format the individual elements of the current instance.</param> /// <returns>An equivalent string representation of the current instance.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> - public string ToString(string format, IFormatProvider formatProvider) + public string ToString(string? format, IFormatProvider? formatProvider) { ThrowHelper.ThrowForUnsupportedVectorBaseType<T>(); diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64.cs index cb6810a659..30d5c4f6ee 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using Internal.Runtime.CompilerServices; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64DebugView_1.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64DebugView_1.cs index 878e29949e..8afffca8a1 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64DebugView_1.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64DebugView_1.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Internal.Runtime.CompilerServices; namespace System.Runtime.Intrinsics diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64_1.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64_1.cs index 99db8c0955..04f26ec772 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64_1.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/Vector64_1.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; @@ -100,7 +101,7 @@ namespace System.Runtime.Intrinsics /// <param name="obj">The object to compare with the current instance.</param> /// <returns><c>true</c> if <paramref name="obj" /> is a <see cref="Vector64{T}" /> and is equal to the current instance; otherwise, <c>false</c>.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> - public override bool Equals(object obj) + public override bool Equals(object? obj) { return (obj is Vector64<T>) && Equals((Vector64<T>)(obj)); } @@ -134,7 +135,7 @@ namespace System.Runtime.Intrinsics /// <param name="format">The format specifier used to format the individual elements of the current instance.</param> /// <returns>An equivalent string representation of the current instance.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> - public string ToString(string format) + public string ToString(string? format) { return ToString(format, formatProvider: null); } @@ -144,7 +145,7 @@ namespace System.Runtime.Intrinsics /// <param name="formatProvider">The format provider used to format the individual elements of the current instance.</param> /// <returns>An equivalent string representation of the current instance.</returns> /// <exception cref="NotSupportedException">The type of the current instance (<typeparamref name="T" />) is not supported.</exception> - public string ToString(string format, IFormatProvider formatProvider) + public string ToString(string? format, IFormatProvider? formatProvider) { ThrowHelper.ThrowForUnsupportedVectorBaseType<T>(); diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Aes.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Aes.PlatformNotSupported.cs index d439defd71..1a0dc5e8f0 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Aes.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Aes.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Aes.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Aes.cs index 45c028c358..c9a07dd5a2 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Aes.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Aes.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx.PlatformNotSupported.cs index 85c5a8bb8f..97d545dc3b 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx.cs index 79c97b886d..65e66f4397 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx2.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx2.PlatformNotSupported.cs index dfe2f626df..ad2244b7b1 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx2.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx2.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx2.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx2.cs index 240d6546fd..33b101b962 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx2.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Avx2.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi1.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi1.PlatformNotSupported.cs index ec2f5475fc..5281097e3b 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi1.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi1.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi1.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi1.cs index 496b8aede5..0f77a1f440 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi1.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi1.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi2.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi2.PlatformNotSupported.cs index 77d3fbfc73..7c32e712ae 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi2.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi2.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi2.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi2.cs index 9b61441dda..6dd18b1b47 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi2.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Bmi2.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Enums.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Enums.cs index 5b0817147a..5dbbbed88f 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Enums.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Enums.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Runtime.Intrinsics.X86 { public enum FloatComparisonMode : byte diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Fma.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Fma.PlatformNotSupported.cs index 91becab4d5..6d9c2931d4 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Fma.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Fma.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Fma.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Fma.cs index ed01805de7..917907c3d7 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Fma.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Fma.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Lzcnt.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Lzcnt.PlatformNotSupported.cs index 7c3bf30667..cdf23928f9 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Lzcnt.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Lzcnt.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; namespace System.Runtime.Intrinsics.X86 diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Lzcnt.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Lzcnt.cs index ff1576e645..99d570e04d 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Lzcnt.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Lzcnt.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Pclmulqdq.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Pclmulqdq.PlatformNotSupported.cs index b79e50a2b7..7ad63c407f 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Pclmulqdq.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Pclmulqdq.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Pclmulqdq.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Pclmulqdq.cs index 332934befc..682d7f9b26 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Pclmulqdq.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Pclmulqdq.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Popcnt.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Popcnt.PlatformNotSupported.cs index 830e32ae63..0a46497d91 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Popcnt.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Popcnt.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; namespace System.Runtime.Intrinsics.X86 diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Popcnt.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Popcnt.cs index c262e99671..687078e3e7 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Popcnt.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Popcnt.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse.PlatformNotSupported.cs index a206eb1d45..ce337e6877 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse.cs index 7c3e27023b..f65aedaf81 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse2.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse2.PlatformNotSupported.cs index 70290b3152..3085aba002 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse2.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse2.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse2.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse2.cs index ea6e3245f9..d9d1307cc8 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse2.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse2.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse3.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse3.PlatformNotSupported.cs index f004266443..d97d4fd544 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse3.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse3.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse3.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse3.cs index 9b971b83b3..f7a710b4fc 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse3.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse3.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse41.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse41.PlatformNotSupported.cs index 26ae9a66e8..25259a9578 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse41.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse41.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse41.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse41.cs index 721037b3f1..834b48856f 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse41.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse41.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse42.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse42.PlatformNotSupported.cs index 1a7aa91df8..ace4a3f0ec 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse42.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse42.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse42.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse42.cs index 9db76c8916..a5eafe3532 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse42.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Sse42.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Ssse3.PlatformNotSupported.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Ssse3.PlatformNotSupported.cs index 45856d6415..8aa0790e03 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Ssse3.PlatformNotSupported.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Ssse3.PlatformNotSupported.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Ssse3.cs b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Ssse3.cs index 0cb59a2115..27ffab0712 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Ssse3.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Intrinsics/X86/Ssse3.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Serialization/DeserializationBlockedException.cs b/src/System.Private.CoreLib/shared/System/Runtime/Serialization/DeserializationBlockedException.cs index 8c8f7809fb..82deb7d614 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Serialization/DeserializationBlockedException.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Serialization/DeserializationBlockedException.cs @@ -2,8 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; - +#nullable enable namespace System.Runtime.Serialization { // Thrown when a dangerous action would be performed during deserialization @@ -21,13 +20,13 @@ namespace System.Runtime.Serialization // Creates a new DeserializationBlockedException with a message indicating an opt-out switch // for a particular part of SerializationGuard - public DeserializationBlockedException(string message) + public DeserializationBlockedException(string? message) : base(message) { HResult = HResults.COR_E_SERIALIZATION; } - public DeserializationBlockedException(Exception innerException) + public DeserializationBlockedException(Exception? innerException) : base(SR.Serialization_DangerousDeserialization, innerException) { HResult = HResults.COR_E_SERIALIZATION; diff --git a/src/System.Private.CoreLib/shared/System/Runtime/Serialization/SerializationException.cs b/src/System.Private.CoreLib/shared/System/Runtime/Serialization/SerializationException.cs index 172e6c5cd5..922a11e6ba 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/Serialization/SerializationException.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/Serialization/SerializationException.cs @@ -2,29 +2,30 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Runtime.Serialization; - +#nullable enable namespace System.Runtime.Serialization { [Serializable] [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public class SerializationException : SystemException { - // Creates a new SerializationException with its message - // string set to a default message. + /// <summary> + /// Creates a new SerializationException with its message + /// string set to a default message. + /// </summary> public SerializationException() : base(SR.SerializationException) { HResult = HResults.COR_E_SERIALIZATION; } - public SerializationException(string message) + public SerializationException(string? message) : base(message) { HResult = HResults.COR_E_SERIALIZATION; } - public SerializationException(string message, Exception innerException) + public SerializationException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_SERIALIZATION; diff --git a/src/System.Private.CoreLib/shared/System/Security/AllowPartiallyTrustedCallersAttribute.cs b/src/System.Private.CoreLib/shared/System/Security/AllowPartiallyTrustedCallersAttribute.cs index 84ad65c4c0..dbdc8cf302 100644 --- a/src/System.Private.CoreLib/shared/System/Security/AllowPartiallyTrustedCallersAttribute.cs +++ b/src/System.Private.CoreLib/shared/System/Security/AllowPartiallyTrustedCallersAttribute.cs @@ -2,12 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Security { // AllowPartiallyTrustedCallersAttribute: // Indicates that the Assembly is secure and can be used by untrusted // and semitrusted clients - // For v.1, this is valid only on Assemblies, but could be expanded to + // For v.1, this is valid only on Assemblies, but could be expanded to // include Module, Method, class [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)] public sealed class AllowPartiallyTrustedCallersAttribute : Attribute @@ -16,4 +17,3 @@ namespace System.Security public PartialTrustVisibilityLevel PartialTrustVisibilityLevel { get; set; } } } - diff --git a/src/System.Private.CoreLib/shared/System/Security/CryptographicException.cs b/src/System.Private.CoreLib/shared/System/Security/CryptographicException.cs index 5f6cecb129..6c97777f56 100644 --- a/src/System.Private.CoreLib/shared/System/Security/CryptographicException.cs +++ b/src/System.Private.CoreLib/shared/System/Security/CryptographicException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Globalization; using System.Runtime.Serialization; @@ -22,17 +23,17 @@ namespace System.Security.Cryptography HResult = hr; } - public CryptographicException(string message) + public CryptographicException(string? message) : base(message) { } - public CryptographicException(string message, Exception inner) + public CryptographicException(string? message, Exception? inner) : base(message, inner) { } - public CryptographicException(string format, string insert) + public CryptographicException(string format, string? insert) : base(string.Format(format, insert)) { } diff --git a/src/System.Private.CoreLib/shared/System/Security/IPermission.cs b/src/System.Private.CoreLib/shared/System/Security/IPermission.cs index cfdf1ebe91..c5cf7f96e3 100644 --- a/src/System.Private.CoreLib/shared/System/Security/IPermission.cs +++ b/src/System.Private.CoreLib/shared/System/Security/IPermission.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Security { #if PROJECTN @@ -11,8 +12,8 @@ namespace System.Security { IPermission Copy(); void Demand(); - IPermission Intersect(IPermission target); - bool IsSubsetOf(IPermission target); - IPermission Union(IPermission target); + IPermission? Intersect(IPermission? target); + bool IsSubsetOf(IPermission? target); + IPermission? Union(IPermission? target); } } diff --git a/src/System.Private.CoreLib/shared/System/Security/ISecurityEncodable.cs b/src/System.Private.CoreLib/shared/System/Security/ISecurityEncodable.cs index 62cdb3f1a3..4fcec04299 100644 --- a/src/System.Private.CoreLib/shared/System/Security/ISecurityEncodable.cs +++ b/src/System.Private.CoreLib/shared/System/Security/ISecurityEncodable.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Security { #if PROJECTN @@ -10,6 +11,6 @@ namespace System.Security public partial interface ISecurityEncodable { void FromXml(SecurityElement e); - SecurityElement ToXml(); + SecurityElement? ToXml(); } } diff --git a/src/System.Private.CoreLib/shared/System/Security/IStackWalk.cs b/src/System.Private.CoreLib/shared/System/Security/IStackWalk.cs index 9e6986a752..a3372bf6b1 100644 --- a/src/System.Private.CoreLib/shared/System/Security/IStackWalk.cs +++ b/src/System.Private.CoreLib/shared/System/Security/IStackWalk.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Security { #if PROJECTN diff --git a/src/System.Private.CoreLib/shared/System/Security/PermissionSet.cs b/src/System.Private.CoreLib/shared/System/Security/PermissionSet.cs index a9198ec925..7d1327df0a 100644 --- a/src/System.Private.CoreLib/shared/System/Security/PermissionSet.cs +++ b/src/System.Private.CoreLib/shared/System/Security/PermissionSet.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Security.Permissions; using System.Collections; using System.Runtime.Serialization; @@ -14,13 +15,13 @@ namespace System.Security public partial class PermissionSet : ICollection, IEnumerable, IDeserializationCallback, ISecurityEncodable, IStackWalk { public PermissionSet(PermissionState state) { } - public PermissionSet(PermissionSet permSet) { } + public PermissionSet(PermissionSet? permSet) { } public virtual int Count { get { return 0; } } public virtual bool IsReadOnly { get { return false; } } public virtual bool IsSynchronized { get { return false; } } public virtual object SyncRoot { get { return this; } } - public IPermission AddPermission(IPermission perm) { return AddPermissionImpl(perm); } - protected virtual IPermission AddPermissionImpl(IPermission perm) { return default(IPermission); } + public IPermission? AddPermission(IPermission? perm) { return AddPermissionImpl(perm); } + protected virtual IPermission? AddPermissionImpl(IPermission? perm) { return default(IPermission); } public void Assert() { } public bool ContainsNonCodeAccessPermissions() { return false; } [Obsolete] @@ -30,26 +31,26 @@ namespace System.Security public void Demand() { } [Obsolete] public void Deny() { throw new PlatformNotSupportedException(SR.PlatformNotSupported_CAS); } - public override bool Equals(object o) => base.Equals(o); + public override bool Equals(object? o) => base.Equals(o); public virtual void FromXml(SecurityElement et) { } public IEnumerator GetEnumerator() { return GetEnumeratorImpl(); } protected virtual IEnumerator GetEnumeratorImpl() { return Array.Empty<object>().GetEnumerator(); } public override int GetHashCode() => base.GetHashCode(); - public IPermission GetPermission(Type permClass) { return GetPermissionImpl(permClass); } - protected virtual IPermission GetPermissionImpl(Type permClass) { return default(IPermission); } - public PermissionSet Intersect(PermissionSet other) { return default(PermissionSet); } + public IPermission? GetPermission(Type? permClass) { return GetPermissionImpl(permClass); } + protected virtual IPermission? GetPermissionImpl(Type? permClass) { return default(IPermission); } + public PermissionSet? Intersect(PermissionSet? other) { return default(PermissionSet); } public bool IsEmpty() { return false; } - public bool IsSubsetOf(PermissionSet target) { return false; } + public bool IsSubsetOf(PermissionSet? target) { return false; } public bool IsUnrestricted() { return false; } public void PermitOnly() { throw new PlatformNotSupportedException(SR.PlatformNotSupported_CAS); } - public IPermission RemovePermission(Type permClass) { return RemovePermissionImpl(permClass); } - protected virtual IPermission RemovePermissionImpl(Type permClass) { return default(IPermission); } + public IPermission? RemovePermission(Type? permClass) { return RemovePermissionImpl(permClass); } + protected virtual IPermission? RemovePermissionImpl(Type? permClass) { return default(IPermission); } public static void RevertAssert() { } - public IPermission SetPermission(IPermission perm) { return SetPermissionImpl(perm); } - protected virtual IPermission SetPermissionImpl(IPermission perm) { return default(IPermission); } + public IPermission? SetPermission(IPermission? perm) { return SetPermissionImpl(perm); } + protected virtual IPermission? SetPermissionImpl(IPermission? perm) { return default(IPermission); } void IDeserializationCallback.OnDeserialization(object sender) { } - public override string ToString() => base.ToString(); - public virtual SecurityElement ToXml() { return default(SecurityElement); } - public PermissionSet Union(PermissionSet other) { return default(PermissionSet); } + public override string ToString() => base.ToString()!; + public virtual SecurityElement? ToXml() { return default(SecurityElement); } + public PermissionSet? Union(PermissionSet? other) { return default(PermissionSet); } } } diff --git a/src/System.Private.CoreLib/shared/System/Security/Principal/IIdentity.cs b/src/System.Private.CoreLib/shared/System/Security/Principal/IIdentity.cs index 177f2b897f..73a6f792a6 100644 --- a/src/System.Private.CoreLib/shared/System/Security/Principal/IIdentity.cs +++ b/src/System.Private.CoreLib/shared/System/Security/Principal/IIdentity.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable // // All identities will implement this interface // @@ -16,10 +17,10 @@ namespace System.Security.Principal public interface IIdentity { // Access to the name string - string Name { get; } + string? Name { get; } // Access to Authentication 'type' info - string AuthenticationType { get; } + string? AuthenticationType { get; } // Determine if this represents the unauthenticated identity bool IsAuthenticated { get; } diff --git a/src/System.Private.CoreLib/shared/System/Security/Principal/IPrincipal.cs b/src/System.Private.CoreLib/shared/System/Security/Principal/IPrincipal.cs index d040c9a866..511ed9bf41 100644 --- a/src/System.Private.CoreLib/shared/System/Security/Principal/IPrincipal.cs +++ b/src/System.Private.CoreLib/shared/System/Security/Principal/IPrincipal.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable // // All roles will implement this interface // @@ -16,7 +17,7 @@ namespace System.Security.Principal public interface IPrincipal { // Retrieve the identity object - IIdentity Identity { get; } + IIdentity? Identity { get; } // Perform a check for a specific role bool IsInRole(string role); diff --git a/src/System.Private.CoreLib/shared/System/Security/SafeBSTRHandle.cs b/src/System.Private.CoreLib/shared/System/Security/SafeBSTRHandle.cs index dd52f42cf7..d5644598be 100644 --- a/src/System.Private.CoreLib/shared/System/Security/SafeBSTRHandle.cs +++ b/src/System.Private.CoreLib/shared/System/Security/SafeBSTRHandle.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime; using System.Diagnostics; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/shared/System/Security/SecureString.Unix.cs b/src/System.Private.CoreLib/shared/System/Security/SecureString.Unix.cs index 0c44cf3df2..6a5e351c56 100644 --- a/src/System.Private.CoreLib/shared/System/Security/SecureString.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Security/SecureString.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime; using System.Runtime.InteropServices; @@ -10,17 +11,17 @@ using System.Text; namespace System.Security { // SecureString attempts to provide a defense-in-depth solution. - // + // // On Windows, this is done with several mechanisms: // 1. keeping the data in unmanaged memory so that copies of it aren't implicitly made by the GC moving it around // 2. zero'ing out that unmanaged memory so that the string is reliably removed from memory when done with it // 3. encrypting the data while it's not being used (it's unencrypted to manipulate and use it) - // + // // On Unix, we do 1 and 2, but we don't do 3 as there's no CryptProtectData equivalent. public sealed partial class SecureString { - private UnmanagedBuffer _buffer; + private UnmanagedBuffer? _buffer; internal SecureString(SecureString str) { @@ -31,6 +32,7 @@ namespace System.Security // Copy the string into the newly allocated space if (_decryptedLength > 0) { + Debug.Assert(str._buffer != null && _buffer != null); ; UnmanagedBuffer.Copy(str._buffer, _buffer, (ulong)(str._decryptedLength * sizeof(char))); } } @@ -45,6 +47,7 @@ namespace System.Security return; } + Debug.Assert(_buffer != null); // Copy the string into the newly allocated space byte* ptr = null; try @@ -73,6 +76,7 @@ namespace System.Security private void ClearCore() { _decryptedLength = 0; + Debug.Assert(_buffer != null); _buffer.Clear(); } @@ -80,6 +84,7 @@ namespace System.Security { // Make sure we have enough space for the new character, then write it at the end. EnsureCapacity(_decryptedLength + 1); + Debug.Assert(_buffer != null); _buffer.Write((ulong)(_decryptedLength * sizeof(char)), c); _decryptedLength++; } @@ -89,6 +94,7 @@ namespace System.Security // Make sure we have enough space for the new character, then shift all of the characters above it and insert it. EnsureCapacity(_decryptedLength + 1); byte* ptr = null; + Debug.Assert(_buffer != null); try { _buffer.AcquirePointer(ref ptr); @@ -111,6 +117,7 @@ namespace System.Security { // Shift down all values above the specified index, then null out the empty space at the end. byte* ptr = null; + Debug.Assert(_buffer != null); try { _buffer.AcquirePointer(ref ptr); @@ -132,6 +139,7 @@ namespace System.Security private void SetAtCore(int index, char c) { // Overwrite the character at the specified index + Debug.Assert(_buffer != null); _buffer.Write((ulong)(index * sizeof(char)), c); } @@ -141,7 +149,8 @@ namespace System.Security IntPtr ptr = IntPtr.Zero; IntPtr result = IntPtr.Zero; byte* bufferPtr = null; - + Debug.Assert(_buffer != null); + try { _buffer.AcquirePointer(ref bufferPtr); @@ -176,6 +185,7 @@ namespace System.Security byte* bufferPtr = null; IntPtr stringPtr = IntPtr.Zero, result = IntPtr.Zero; + Debug.Assert(_buffer != null); try { _buffer.AcquirePointer(ref bufferPtr); @@ -203,7 +213,7 @@ namespace System.Security } finally { - // If there was a failure, such that result isn't initialized, + // If there was a failure, such that result isn't initialized, // release the string if we had one. if (stringPtr != IntPtr.Zero && result == IntPtr.Zero) { diff --git a/src/System.Private.CoreLib/shared/System/Security/SecureString.Windows.cs b/src/System.Private.CoreLib/shared/System/Security/SecureString.Windows.cs index 8174dbfb7f..ddbbf4a962 100644 --- a/src/System.Private.CoreLib/shared/System/Security/SecureString.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/Security/SecureString.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime; using System.Runtime.InteropServices; @@ -18,6 +19,7 @@ namespace System.Security Debug.Assert(str._encrypted, "Expected to be used only on encrypted SecureStrings"); AllocateBuffer(str._buffer.Length); + Debug.Assert(_buffer != null); SafeBSTRHandle.Copy(str._buffer, _buffer, str._buffer.Length * sizeof(char)); _decryptedLength = str._decryptedLength; @@ -32,6 +34,7 @@ namespace System.Security _decryptedLength = length; byte* bufferPtr = null; + Debug.Assert(_buffer != null); try { _buffer.AcquirePointer(ref bufferPtr); @@ -54,6 +57,7 @@ namespace System.Security try { EnsureCapacity(_decryptedLength + 1); + Debug.Assert(_buffer != null); _buffer.Write<char>((uint)_decryptedLength * sizeof(char), c); _decryptedLength++; } @@ -66,6 +70,7 @@ namespace System.Security private void ClearCore() { _decryptedLength = 0; + Debug.Assert(_buffer != null); _buffer.ClearBuffer(); } @@ -82,6 +87,7 @@ namespace System.Security { byte* bufferPtr = null; UnprotectMemory(); + Debug.Assert(_buffer != null); try { EnsureCapacity(_decryptedLength + 1); @@ -110,6 +116,7 @@ namespace System.Security { byte* bufferPtr = null; UnprotectMemory(); + Debug.Assert(_buffer != null); try { _buffer.AcquirePointer(ref bufferPtr); @@ -136,6 +143,7 @@ namespace System.Security UnprotectMemory(); try { + Debug.Assert(_buffer != null); _buffer.Write<char>((uint)index * sizeof(char), c); } finally @@ -152,6 +160,7 @@ namespace System.Security byte* bufferPtr = null; UnprotectMemory(); + Debug.Assert(_buffer != null); try { _buffer.AcquirePointer(ref bufferPtr); @@ -190,6 +199,7 @@ namespace System.Security byte* bufferPtr = null; UnprotectMemory(); + Debug.Assert(_buffer != null); try { _buffer.AcquirePointer(ref bufferPtr); @@ -236,7 +246,7 @@ namespace System.Security // ----------------------------- private const int BlockSize = (int)Interop.Crypt32.CRYPTPROTECTMEMORY_BLOCK_SIZE / sizeof(char); - private SafeBSTRHandle _buffer; + private SafeBSTRHandle? _buffer; private bool _encrypted; private void AllocateBuffer(uint size) @@ -256,6 +266,7 @@ namespace System.Security throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_Capacity); } + Debug.Assert(_buffer != null); if (((uint)capacity * sizeof(char)) <= _buffer.ByteLength) { return; @@ -270,6 +281,7 @@ namespace System.Security private void ProtectMemory() { + Debug.Assert(_buffer != null); Debug.Assert(!_buffer.IsInvalid, "Invalid buffer!"); if (_decryptedLength != 0 && @@ -284,6 +296,7 @@ namespace System.Security private void UnprotectMemory() { + Debug.Assert(_buffer != null); Debug.Assert(!_buffer.IsInvalid, "Invalid buffer!"); if (_decryptedLength != 0 && diff --git a/src/System.Private.CoreLib/shared/System/Security/SecureString.cs b/src/System.Private.CoreLib/shared/System/Security/SecureString.cs index cdee9c9076..ece3ffa7c4 100644 --- a/src/System.Private.CoreLib/shared/System/Security/SecureString.cs +++ b/src/System.Private.CoreLib/shared/System/Security/SecureString.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; @@ -69,7 +70,7 @@ namespace System.Security } } - // Do a deep-copy of the SecureString + // Do a deep-copy of the SecureString public SecureString Copy() { lock (_methodLock) diff --git a/src/System.Private.CoreLib/shared/System/Security/SecurityCriticalAttribute.cs b/src/System.Private.CoreLib/shared/System/Security/SecurityCriticalAttribute.cs index 2bf1700afb..15c62e04dc 100644 --- a/src/System.Private.CoreLib/shared/System/Security/SecurityCriticalAttribute.cs +++ b/src/System.Private.CoreLib/shared/System/Security/SecurityCriticalAttribute.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Security { // SecurityCriticalAttribute @@ -33,4 +34,3 @@ namespace System.Security #pragma warning restore 618 } } - diff --git a/src/System.Private.CoreLib/shared/System/Security/SecurityElement.cs b/src/System.Private.CoreLib/shared/System/Security/SecurityElement.cs index 8bd335cad9..974d9a1f55 100644 --- a/src/System.Private.CoreLib/shared/System/Security/SecurityElement.cs +++ b/src/System.Private.CoreLib/shared/System/Security/SecurityElement.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information.s +#nullable enable using System.Collections; using System.Diagnostics; using System.Globalization; @@ -21,7 +22,7 @@ namespace System.Security string GetTag(); - string Attribute(string attributeName); + string? Attribute(string attributeName); } #if PROJECTN @@ -29,10 +30,10 @@ namespace System.Security #endif public sealed class SecurityElement : ISecurityElementFactory { - internal string _tag; - internal string _text; - private ArrayList _children; - internal ArrayList _attributes; + internal string _tag = null!; + internal string? _text; + private ArrayList? _children; + internal ArrayList? _attributes; private const int AttributesTypical = 4 * 2; // 4 attributes, times 2 strings per attribute private const int ChildrenTypical = 1; @@ -70,7 +71,7 @@ namespace System.Security _text = null; } - public SecurityElement(string tag, string text) + public SecurityElement(string tag, string? text) { if (tag == null) throw new ArgumentNullException(nameof(tag)); @@ -106,7 +107,7 @@ namespace System.Security } } - public Hashtable Attributes + public Hashtable? Attributes { get { @@ -161,7 +162,7 @@ namespace System.Security } } - public string Text + public string? Text { get { @@ -184,7 +185,7 @@ namespace System.Security } } - public ArrayList Children + public ArrayList? Children { get { @@ -209,7 +210,7 @@ namespace System.Security for (int i = 0; i < _children.Count; ++i) { - ISecurityElementFactory iseFactory = _children[i] as ISecurityElementFactory; + ISecurityElementFactory? iseFactory = _children[i] as ISecurityElementFactory; if (iseFactory != null && !(_children[i] is SecurityElement)) _children[i] = iseFactory.CreateSecurityElement(); } @@ -269,7 +270,7 @@ namespace System.Security _children.Add(child); } - public bool Equal(SecurityElement other) + public bool Equal(SecurityElement? other) { if (other == null) return false; @@ -349,7 +350,7 @@ namespace System.Security return element; } - public static bool IsValidTag(string tag) + public static bool IsValidTag(string? tag) { if (tag == null) return false; @@ -357,7 +358,7 @@ namespace System.Security return tag.IndexOfAny(s_tagIllegalCharacters) == -1; } - public static bool IsValidText(string text) + public static bool IsValidText(string? text) { if (text == null) return false; @@ -365,12 +366,12 @@ namespace System.Security return text.IndexOfAny(s_textIllegalCharacters) == -1; } - public static bool IsValidAttributeName(string name) + public static bool IsValidAttributeName(string? name) { return IsValidTag(name); } - public static bool IsValidAttributeValue(string value) + public static bool IsValidAttributeValue(string? value) { if (value == null) return false; @@ -396,12 +397,12 @@ namespace System.Security return c.ToString(); } - public static string Escape(string str) + public static string? Escape(string? str) { if (str == null) return null; - StringBuilder sb = null; + StringBuilder? sb = null; int strLen = str.Length; int index; // Pointer into the string that indicates the location of the current '&' character @@ -461,12 +462,12 @@ namespace System.Security return str[index].ToString(); } - private static string Unescape(string str) + private static string? Unescape(string? str) { if (str == null) return null; - StringBuilder sb = null; + StringBuilder? sb = null; int strLen = str.Length; int index; // Pointer into the string that indicates the location of the current '&' character @@ -508,7 +509,7 @@ namespace System.Security return sb.ToString(); } - private void ToString(string indent, object obj, Action<object, string> write) + private void ToString(string indent, object obj, Action<object, string?> write) { write(obj, "<"); write(obj, _tag); @@ -573,7 +574,7 @@ namespace System.Security } } - public string Attribute(string name) + public string? Attribute(string name) { if (name == null) throw new ArgumentNullException(nameof(name)); @@ -605,7 +606,7 @@ namespace System.Security return null; } - public SecurityElement SearchForChildByTag(string tag) + public SecurityElement? SearchForChildByTag(string tag) { // Go through all the children and see if we can // find the ones that are asked for (matching tags) @@ -613,7 +614,7 @@ namespace System.Security throw new ArgumentNullException(nameof(tag)); // Note: we don't check for a valid tag here because - // an invalid tag simply won't be found. + // an invalid tag simply won't be found. if (_children == null) return null; foreach (SecurityElement current in _children) @@ -624,7 +625,7 @@ namespace System.Security return null; } - public string SearchForTextOfTag(string tag) + public string? SearchForTextOfTag(string tag) { // Search on each child in order and each // child's child, depth-first @@ -632,22 +633,22 @@ namespace System.Security throw new ArgumentNullException(nameof(tag)); // Note: we don't check for a valid tag here because - // an invalid tag simply won't be found. + // an invalid tag simply won't be found. if (string.Equals(_tag, tag)) return Unescape(_text); if (_children == null) return null; - foreach (SecurityElement child in Children) + foreach (SecurityElement child in Children!) { - string text = child.SearchForTextOfTag(tag); + string? text = child.SearchForTextOfTag(tag); if (text != null) return text; } return null; } - public static SecurityElement FromString(string xml) + public static SecurityElement? FromString(string xml) { if (xml == null) throw new ArgumentNullException(nameof(xml)); @@ -672,7 +673,7 @@ namespace System.Security return ((SecurityElement)this).Copy(); } - string ISecurityElementFactory.Attribute(string attributeName) + string? ISecurityElementFactory.Attribute(string attributeName) { return ((SecurityElement)this).Attribute(attributeName); } diff --git a/src/System.Private.CoreLib/shared/System/Security/SecurityException.cs b/src/System.Private.CoreLib/shared/System/Security/SecurityException.cs index 61504c3ba1..f1494757d4 100644 --- a/src/System.Private.CoreLib/shared/System/Security/SecurityException.cs +++ b/src/System.Private.CoreLib/shared/System/Security/SecurityException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Reflection; using System.Runtime.Serialization; @@ -24,26 +25,26 @@ namespace System.Security HResult = HResults.COR_E_SECURITY; } - public SecurityException(string message) + public SecurityException(string? message) : base(message) { HResult = HResults.COR_E_SECURITY; } - public SecurityException(string message, Exception inner) + public SecurityException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_SECURITY; } - public SecurityException(string message, Type type) + public SecurityException(string? message, Type? type) : base(message) { HResult = HResults.COR_E_SECURITY; PermissionType = type; } - public SecurityException(string message, Type type, string state) + public SecurityException(string? message, Type? type, string? state) : base(message) { HResult = HResults.COR_E_SECURITY; @@ -66,7 +67,7 @@ namespace System.Security public override void GetObjectData(SerializationInfo info, StreamingContext context) { - base.GetObjectData(info, context); + base.GetObjectData(info, context); info.AddValue(DemandedName, Demanded, typeof(string)); info.AddValue(GrantedSetName, GrantedSet, typeof(string)); info.AddValue(RefusedSetName, RefusedSet, typeof(string)); @@ -75,15 +76,15 @@ namespace System.Security info.AddValue(UrlName, Url, typeof(string)); } - public object Demanded { get; set; } - public object DenySetInstance { get; set; } - public AssemblyName FailedAssemblyInfo { get; set; } - public string GrantedSet { get; set; } - public MethodInfo Method { get; set; } - public string PermissionState { get; set; } - public Type PermissionType { get; set; } - public object PermitOnlySetInstance { get; set; } - public string RefusedSet { get; set; } - public string Url { get; set; } + public object? Demanded { get; set; } + public object? DenySetInstance { get; set; } + public AssemblyName? FailedAssemblyInfo { get; set; } + public string? GrantedSet { get; set; } + public MethodInfo? Method { get; set; } + public string? PermissionState { get; set; } + public Type? PermissionType { get; set; } + public object? PermitOnlySetInstance { get; set; } + public string? RefusedSet { get; set; } + public string? Url { get; set; } } } diff --git a/src/System.Private.CoreLib/shared/System/Security/SecurityRulesAttribute.cs b/src/System.Private.CoreLib/shared/System/Security/SecurityRulesAttribute.cs index ad17087f8b..d3f03089dc 100644 --- a/src/System.Private.CoreLib/shared/System/Security/SecurityRulesAttribute.cs +++ b/src/System.Private.CoreLib/shared/System/Security/SecurityRulesAttribute.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Security { // SecurityRulesAttribute @@ -25,4 +26,3 @@ namespace System.Security public SecurityRuleSet RuleSet { get; } } } - diff --git a/src/System.Private.CoreLib/shared/System/Security/SecuritySafeCriticalAttribute.cs b/src/System.Private.CoreLib/shared/System/Security/SecuritySafeCriticalAttribute.cs index ee2e4b0499..2a2e8e1945 100644 --- a/src/System.Private.CoreLib/shared/System/Security/SecuritySafeCriticalAttribute.cs +++ b/src/System.Private.CoreLib/shared/System/Security/SecuritySafeCriticalAttribute.cs @@ -2,9 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Security { - // SecuritySafeCriticalAttribute: + // SecuritySafeCriticalAttribute: // Indicates that the code may contain violations to the security critical rules (e.g. transitions from // critical to non-public transparent, transparent to non-public critical, etc.), has been audited for // security concerns and is considered security clean. Also indicates that the code is considered SecurityCritical. diff --git a/src/System.Private.CoreLib/shared/System/Security/SecurityTransparentAttribute.cs b/src/System.Private.CoreLib/shared/System/Security/SecurityTransparentAttribute.cs index 03f41387ae..a53d61097d 100644 --- a/src/System.Private.CoreLib/shared/System/Security/SecurityTransparentAttribute.cs +++ b/src/System.Private.CoreLib/shared/System/Security/SecurityTransparentAttribute.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Security { // SecurityTransparentAttribute: @@ -16,4 +17,3 @@ namespace System.Security public SecurityTransparentAttribute() { } } } - diff --git a/src/System.Private.CoreLib/shared/System/Security/SecurityTreatAsSafeAttribute.cs b/src/System.Private.CoreLib/shared/System/Security/SecurityTreatAsSafeAttribute.cs index 7a95122bf0..85f7da59b9 100644 --- a/src/System.Private.CoreLib/shared/System/Security/SecurityTreatAsSafeAttribute.cs +++ b/src/System.Private.CoreLib/shared/System/Security/SecurityTreatAsSafeAttribute.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Security { // SecurityTreatAsSafeAttribute: @@ -29,4 +30,3 @@ namespace System.Security public SecurityTreatAsSafeAttribute() { } } } - diff --git a/src/System.Private.CoreLib/shared/System/Security/SuppressUnmanagedCodeSecurityAttribute.cs b/src/System.Private.CoreLib/shared/System/Security/SuppressUnmanagedCodeSecurityAttribute.cs index 5312644b81..768943b1eb 100644 --- a/src/System.Private.CoreLib/shared/System/Security/SuppressUnmanagedCodeSecurityAttribute.cs +++ b/src/System.Private.CoreLib/shared/System/Security/SuppressUnmanagedCodeSecurityAttribute.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Security { // SuppressUnmanagedCodeSecurityAttribute: @@ -12,4 +13,3 @@ namespace System.Security public SuppressUnmanagedCodeSecurityAttribute() { } } } - diff --git a/src/System.Private.CoreLib/shared/System/Security/UnverifiableCodeAttribute.cs b/src/System.Private.CoreLib/shared/System/Security/UnverifiableCodeAttribute.cs index 1560b6617b..4a5e0785c0 100644 --- a/src/System.Private.CoreLib/shared/System/Security/UnverifiableCodeAttribute.cs +++ b/src/System.Private.CoreLib/shared/System/Security/UnverifiableCodeAttribute.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Security { // UnverifiableCodeAttribute: @@ -12,4 +13,3 @@ namespace System.Security public UnverifiableCodeAttribute() { } } } - diff --git a/src/System.Private.CoreLib/shared/System/Security/VerificationException.cs b/src/System.Private.CoreLib/shared/System/Security/VerificationException.cs index e2afd4cabe..7515f39235 100644 --- a/src/System.Private.CoreLib/shared/System/Security/VerificationException.cs +++ b/src/System.Private.CoreLib/shared/System/Security/VerificationException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Security @@ -16,13 +17,13 @@ namespace System.Security HResult = HResults.COR_E_VERIFICATION; } - public VerificationException(string message) + public VerificationException(string? message) : base(message) { HResult = HResults.COR_E_VERIFICATION; } - public VerificationException(string message, Exception innerException) + public VerificationException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_VERIFICATION; diff --git a/src/System.Private.CoreLib/shared/System/Single.cs b/src/System.Private.CoreLib/shared/System/Single.cs index 4a0a06f139..6374ecb337 100644 --- a/src/System.Private.CoreLib/shared/System/Single.cs +++ b/src/System.Private.CoreLib/shared/System/Single.cs @@ -11,6 +11,7 @@ ** ===========================================================*/ +#nullable enable using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -117,7 +118,7 @@ namespace System // null is considered to be less than any instance. // If object is not of type Single, this method throws an ArgumentException. // - public int CompareTo(object value) + public int CompareTo(object? value) { if (value == null) { @@ -189,7 +190,7 @@ namespace System return left >= right; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (!(obj is float)) { @@ -233,22 +234,22 @@ namespace System return Number.FormatSingle(m_value, null, NumberFormatInfo.CurrentInfo); } - public string ToString(IFormatProvider provider) + public string ToString(IFormatProvider? provider) { return Number.FormatSingle(m_value, null, NumberFormatInfo.GetInstance(provider)); } - public string ToString(string format) + public string ToString(string? format) { return Number.FormatSingle(m_value, format, NumberFormatInfo.CurrentInfo); } - public string ToString(string format, IFormatProvider provider) + public string ToString(string? format, IFormatProvider? provider) { return Number.FormatSingle(m_value, format, NumberFormatInfo.GetInstance(provider)); } - public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format = default, IFormatProvider provider = null) + public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format = default, IFormatProvider? provider = null) { return Number.TryFormatSingle(m_value, format, NumberFormatInfo.GetInstance(provider), destination, out charsWritten); } @@ -274,26 +275,26 @@ namespace System return Number.ParseSingle(s, style, NumberFormatInfo.CurrentInfo); } - public static float Parse(string s, IFormatProvider provider) + public static float Parse(string s, IFormatProvider? provider) { if (s == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.s); return Number.ParseSingle(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.GetInstance(provider)); } - public static float Parse(string s, NumberStyles style, IFormatProvider provider) + public static float Parse(string s, NumberStyles style, IFormatProvider? provider) { NumberFormatInfo.ValidateParseStyleFloatingPoint(style); if (s == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.s); return Number.ParseSingle(s, style, NumberFormatInfo.GetInstance(provider)); } - public static float Parse(ReadOnlySpan<char> s, NumberStyles style = NumberStyles.Float | NumberStyles.AllowThousands, IFormatProvider provider = null) + public static float Parse(ReadOnlySpan<char> s, NumberStyles style = NumberStyles.Float | NumberStyles.AllowThousands, IFormatProvider? provider = null) { NumberFormatInfo.ValidateParseStyleFloatingPoint(style); return Number.ParseSingle(s, style, NumberFormatInfo.GetInstance(provider)); } - public static bool TryParse(string s, out float result) + public static bool TryParse(string? s, out float result) { if (s == null) { @@ -309,7 +310,7 @@ namespace System return TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo, out result); } - public static bool TryParse(string s, NumberStyles style, IFormatProvider provider, out float result) + public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out float result) { NumberFormatInfo.ValidateParseStyleFloatingPoint(style); @@ -322,7 +323,7 @@ namespace System return TryParse((ReadOnlySpan<char>)s, style, NumberFormatInfo.GetInstance(provider), out result); } - public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider provider, out float result) + public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider, out float result) { NumberFormatInfo.ValidateParseStyleFloatingPoint(style); return TryParse(s, style, NumberFormatInfo.GetInstance(provider), out result); @@ -343,77 +344,77 @@ namespace System } - bool IConvertible.ToBoolean(IFormatProvider provider) + bool IConvertible.ToBoolean(IFormatProvider? provider) { return Convert.ToBoolean(m_value); } - char IConvertible.ToChar(IFormatProvider provider) + char IConvertible.ToChar(IFormatProvider? provider) { throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Single", "Char")); } - sbyte IConvertible.ToSByte(IFormatProvider provider) + sbyte IConvertible.ToSByte(IFormatProvider? provider) { return Convert.ToSByte(m_value); } - byte IConvertible.ToByte(IFormatProvider provider) + byte IConvertible.ToByte(IFormatProvider? provider) { return Convert.ToByte(m_value); } - short IConvertible.ToInt16(IFormatProvider provider) + short IConvertible.ToInt16(IFormatProvider? provider) { return Convert.ToInt16(m_value); } - ushort IConvertible.ToUInt16(IFormatProvider provider) + ushort IConvertible.ToUInt16(IFormatProvider? provider) { return Convert.ToUInt16(m_value); } - int IConvertible.ToInt32(IFormatProvider provider) + int IConvertible.ToInt32(IFormatProvider? provider) { return Convert.ToInt32(m_value); } - uint IConvertible.ToUInt32(IFormatProvider provider) + uint IConvertible.ToUInt32(IFormatProvider? provider) { return Convert.ToUInt32(m_value); } - long IConvertible.ToInt64(IFormatProvider provider) + long IConvertible.ToInt64(IFormatProvider? provider) { return Convert.ToInt64(m_value); } - ulong IConvertible.ToUInt64(IFormatProvider provider) + ulong IConvertible.ToUInt64(IFormatProvider? provider) { return Convert.ToUInt64(m_value); } - float IConvertible.ToSingle(IFormatProvider provider) + float IConvertible.ToSingle(IFormatProvider? provider) { return m_value; } - double IConvertible.ToDouble(IFormatProvider provider) + double IConvertible.ToDouble(IFormatProvider? provider) { return Convert.ToDouble(m_value); } - decimal IConvertible.ToDecimal(IFormatProvider provider) + decimal IConvertible.ToDecimal(IFormatProvider? provider) { return Convert.ToDecimal(m_value); } - DateTime IConvertible.ToDateTime(IFormatProvider provider) + DateTime IConvertible.ToDateTime(IFormatProvider? provider) { throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Single", "DateTime")); } - object IConvertible.ToType(Type type, IFormatProvider provider) + object IConvertible.ToType(Type type, IFormatProvider? provider) { return Convert.DefaultToType((IConvertible)this, type, provider); } diff --git a/src/System.Private.CoreLib/shared/System/StackOverflowException.cs b/src/System.Private.CoreLib/shared/System/StackOverflowException.cs index a603ea88b2..556c38dce7 100644 --- a/src/System.Private.CoreLib/shared/System/StackOverflowException.cs +++ b/src/System.Private.CoreLib/shared/System/StackOverflowException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -25,13 +26,13 @@ namespace System HResult = HResults.COR_E_STACKOVERFLOW; } - public StackOverflowException(string message) + public StackOverflowException(string? message) : base(message) { HResult = HResults.COR_E_STACKOVERFLOW; } - public StackOverflowException(string message, Exception innerException) + public StackOverflowException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_STACKOVERFLOW; diff --git a/src/System.Private.CoreLib/shared/System/String.Manipulation.cs b/src/System.Private.CoreLib/shared/System/String.Manipulation.cs index bd56d0c33a..dc7f01591b 100644 --- a/src/System.Private.CoreLib/shared/System/String.Manipulation.cs +++ b/src/System.Private.CoreLib/shared/System/String.Manipulation.cs @@ -34,14 +34,7 @@ namespace System } } - public static string Concat(object? arg0) - { - if (arg0 == null) - { - return string.Empty; - } - return arg0.ToString(); - } + public static string Concat(object? arg0) => arg0?.ToString() ?? string.Empty; public static string Concat(object? arg0, object? arg1) { diff --git a/src/System.Private.CoreLib/shared/System/String.Searching.cs b/src/System.Private.CoreLib/shared/System/String.Searching.cs index de91b3b57e..85b82da2a5 100644 --- a/src/System.Private.CoreLib/shared/System/String.Searching.cs +++ b/src/System.Private.CoreLib/shared/System/String.Searching.cs @@ -19,7 +19,7 @@ namespace System return SpanHelpers.IndexOf( ref _firstChar, Length, - ref value!._firstChar, // TODO-NULLABLE: Compiler Bug? + ref value!._firstChar, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 value.Length) >= 0; } diff --git a/src/System.Private.CoreLib/shared/System/SystemException.cs b/src/System.Private.CoreLib/shared/System/SystemException.cs index 9a1daf2104..8d8484de16 100644 --- a/src/System.Private.CoreLib/shared/System/SystemException.cs +++ b/src/System.Private.CoreLib/shared/System/SystemException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System @@ -16,13 +17,13 @@ namespace System HResult = HResults.COR_E_SYSTEM; } - public SystemException(string message) + public SystemException(string? message) : base(message) { HResult = HResults.COR_E_SYSTEM; } - public SystemException(string message, Exception innerException) + public SystemException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_SYSTEM; diff --git a/src/System.Private.CoreLib/shared/System/Threading/AbandonedMutexException.cs b/src/System.Private.CoreLib/shared/System/Threading/AbandonedMutexException.cs index bd504dd27a..1517c7e06e 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/AbandonedMutexException.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/AbandonedMutexException.cs @@ -7,9 +7,7 @@ // AbandonedMutexs indicate serious error in user code or machine state. //////////////////////////////////////////////////////////////////////////////// -using System; -using System.Threading; -using System.Runtime.InteropServices; +#nullable enable using System.Runtime.Serialization; namespace System.Threading @@ -19,7 +17,7 @@ namespace System.Threading public class AbandonedMutexException : SystemException { private int _mutexIndex = -1; - private Mutex _mutex = null; + private Mutex? _mutex = null; public AbandonedMutexException() : base(SR.Threading_AbandonedMutexException) @@ -27,33 +25,33 @@ namespace System.Threading HResult = HResults.COR_E_ABANDONEDMUTEX; } - public AbandonedMutexException(string message) + public AbandonedMutexException(string? message) : base(message) { HResult = HResults.COR_E_ABANDONEDMUTEX; } - public AbandonedMutexException(string message, Exception inner) + public AbandonedMutexException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_ABANDONEDMUTEX; } - public AbandonedMutexException(int location, WaitHandle handle) + public AbandonedMutexException(int location, WaitHandle? handle) : base(SR.Threading_AbandonedMutexException) { HResult = HResults.COR_E_ABANDONEDMUTEX; SetupException(location, handle); } - public AbandonedMutexException(string message, int location, WaitHandle handle) + public AbandonedMutexException(string? message, int location, WaitHandle? handle) : base(message) { HResult = HResults.COR_E_ABANDONEDMUTEX; SetupException(location, handle); } - public AbandonedMutexException(string message, Exception inner, int location, WaitHandle handle) + public AbandonedMutexException(string? message, Exception? inner, int location, WaitHandle? handle) : base(message, inner) { HResult = HResults.COR_E_ABANDONEDMUTEX; @@ -65,14 +63,13 @@ namespace System.Threading { } - private void SetupException(int location, WaitHandle handle) + private void SetupException(int location, WaitHandle? handle) { _mutexIndex = location; - if (handle != null) - _mutex = handle as Mutex; + _mutex = handle as Mutex; } - public Mutex Mutex => _mutex; + public Mutex? Mutex => _mutex; public int MutexIndex => _mutexIndex; } } diff --git a/src/System.Private.CoreLib/shared/System/Threading/ApartmentState.cs b/src/System.Private.CoreLib/shared/System/Threading/ApartmentState.cs index 47c1677cb5..961979282f 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ApartmentState.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ApartmentState.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { public enum ApartmentState diff --git a/src/System.Private.CoreLib/shared/System/Threading/AsyncLocal.cs b/src/System.Private.CoreLib/shared/System/Threading/AsyncLocal.cs index 12d6502432..463289ae55 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/AsyncLocal.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/AsyncLocal.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Diagnostics; @@ -38,7 +39,7 @@ namespace System.Threading // public sealed class AsyncLocal<T> : IAsyncLocal { - private readonly Action<AsyncLocalValueChangedArgs<T>> m_valueChangedHandler; + private readonly Action<AsyncLocalValueChangedArgs<T>>? m_valueChangedHandler; // // Constructs an AsyncLocal<T> that does not receive change notifications. @@ -51,7 +52,7 @@ namespace System.Threading // Constructs an AsyncLocal<T> with a delegate that is called whenever the current value changes // on any thread. // - public AsyncLocal(Action<AsyncLocalValueChangedArgs<T>> valueChangedHandler) + public AsyncLocal(Action<AsyncLocalValueChangedArgs<T>>? valueChangedHandler) { m_valueChangedHandler = valueChangedHandler; } @@ -60,8 +61,8 @@ namespace System.Threading { get { - object obj = ExecutionContext.GetLocalValue(this); - return (obj == null) ? default : (T)obj; + object? obj = ExecutionContext.GetLocalValue(this); + return (obj == null) ? default! : (T)obj; // TODO-NULLABLE-GENERIC } set { @@ -69,11 +70,11 @@ namespace System.Threading } } - void IAsyncLocal.OnValueChanged(object previousValueObj, object currentValueObj, bool contextChanged) + void IAsyncLocal.OnValueChanged(object? previousValueObj, object? currentValueObj, bool contextChanged) { Debug.Assert(m_valueChangedHandler != null); - T previousValue = previousValueObj == null ? default : (T)previousValueObj; - T currentValue = currentValueObj == null ? default : (T)currentValueObj; + T previousValue = previousValueObj == null ? default! : (T)previousValueObj; // TODO-NULLABLE-GENERIC + T currentValue = currentValueObj == null ? default! : (T)currentValueObj; // TODO-NULLABLE-GENERIC m_valueChangedHandler(new AsyncLocalValueChangedArgs<T>(previousValue, currentValue, contextChanged)); } } @@ -83,7 +84,7 @@ namespace System.Threading // internal interface IAsyncLocal { - void OnValueChanged(object previousValue, object currentValue, bool contextChanged); + void OnValueChanged(object? previousValue, object? currentValue, bool contextChanged); } public readonly struct AsyncLocalValueChangedArgs<T> @@ -112,8 +113,8 @@ namespace System.Threading // internal interface IAsyncLocalValueMap { - bool TryGetValue(IAsyncLocal key, out object value); - IAsyncLocalValueMap Set(IAsyncLocal key, object value, bool treatNullValueAsNonexistent); + bool TryGetValue(IAsyncLocal key, out object? value); + IAsyncLocalValueMap Set(IAsyncLocal key, object? value, bool treatNullValueAsNonexistent); } // @@ -131,7 +132,7 @@ namespace System.Threading return asyncLocalValueMap == Empty; } - public static IAsyncLocalValueMap Create(IAsyncLocal key, object value, bool treatNullValueAsNonexistent) + public static IAsyncLocalValueMap Create(IAsyncLocal key, object? value, bool treatNullValueAsNonexistent) { // If the value isn't null or a null value may not be treated as nonexistent, then create a new one-element map // to store the key/value pair. Otherwise, use the empty map. @@ -143,7 +144,7 @@ namespace System.Threading // Instance without any key/value pairs. Used as a singleton/ private sealed class EmptyAsyncLocalValueMap : IAsyncLocalValueMap { - public IAsyncLocalValueMap Set(IAsyncLocal key, object value, bool treatNullValueAsNonexistent) + public IAsyncLocalValueMap Set(IAsyncLocal key, object? value, bool treatNullValueAsNonexistent) { // If the value isn't null or a null value may not be treated as nonexistent, then create a new one-element map // to store the key/value pair. Otherwise, use the empty map. @@ -152,7 +153,7 @@ namespace System.Threading (IAsyncLocalValueMap)this; } - public bool TryGetValue(IAsyncLocal key, out object value) + public bool TryGetValue(IAsyncLocal key, out object? value) { value = null; return false; @@ -163,14 +164,14 @@ namespace System.Threading private sealed class OneElementAsyncLocalValueMap : IAsyncLocalValueMap { private readonly IAsyncLocal _key1; - private readonly object _value1; + private readonly object? _value1; - public OneElementAsyncLocalValueMap(IAsyncLocal key, object value) + public OneElementAsyncLocalValueMap(IAsyncLocal key, object? value) { _key1 = key; _value1 = value; } - public IAsyncLocalValueMap Set(IAsyncLocal key, object value, bool treatNullValueAsNonexistent) + public IAsyncLocalValueMap Set(IAsyncLocal key, object? value, bool treatNullValueAsNonexistent) { if (value != null || !treatNullValueAsNonexistent) { @@ -190,7 +191,7 @@ namespace System.Threading } } - public bool TryGetValue(IAsyncLocal key, out object value) + public bool TryGetValue(IAsyncLocal key, out object? value) { if (ReferenceEquals(key, _key1)) { @@ -209,15 +210,15 @@ namespace System.Threading private sealed class TwoElementAsyncLocalValueMap : IAsyncLocalValueMap { private readonly IAsyncLocal _key1, _key2; - private readonly object _value1, _value2; + private readonly object? _value1, _value2; - public TwoElementAsyncLocalValueMap(IAsyncLocal key1, object value1, IAsyncLocal key2, object value2) + public TwoElementAsyncLocalValueMap(IAsyncLocal key1, object? value1, IAsyncLocal key2, object? value2) { _key1 = key1; _value1 = value1; _key2 = key2; _value2 = value2; } - public IAsyncLocalValueMap Set(IAsyncLocal key, object value, bool treatNullValueAsNonexistent) + public IAsyncLocalValueMap Set(IAsyncLocal key, object? value, bool treatNullValueAsNonexistent) { if (value != null || !treatNullValueAsNonexistent) { @@ -239,7 +240,7 @@ namespace System.Threading } } - public bool TryGetValue(IAsyncLocal key, out object value) + public bool TryGetValue(IAsyncLocal key, out object? value) { if (ReferenceEquals(key, _key1)) { @@ -263,16 +264,16 @@ namespace System.Threading private sealed class ThreeElementAsyncLocalValueMap : IAsyncLocalValueMap { private readonly IAsyncLocal _key1, _key2, _key3; - private readonly object _value1, _value2, _value3; + private readonly object? _value1, _value2, _value3; - public ThreeElementAsyncLocalValueMap(IAsyncLocal key1, object value1, IAsyncLocal key2, object value2, IAsyncLocal key3, object value3) + public ThreeElementAsyncLocalValueMap(IAsyncLocal key1, object? value1, IAsyncLocal key2, object? value2, IAsyncLocal key3, object? value3) { _key1 = key1; _value1 = value1; _key2 = key2; _value2 = value2; _key3 = key3; _value3 = value3; } - public IAsyncLocalValueMap Set(IAsyncLocal key, object value, bool treatNullValueAsNonexistent) + public IAsyncLocalValueMap Set(IAsyncLocal key, object? value, bool treatNullValueAsNonexistent) { if (value != null || !treatNullValueAsNonexistent) { @@ -303,7 +304,7 @@ namespace System.Threading } } - public bool TryGetValue(IAsyncLocal key, out object value) + public bool TryGetValue(IAsyncLocal key, out object? value) { if (ReferenceEquals(key, _key1)) { @@ -332,21 +333,21 @@ namespace System.Threading private sealed class MultiElementAsyncLocalValueMap : IAsyncLocalValueMap { internal const int MaxMultiElements = 16; - private readonly KeyValuePair<IAsyncLocal, object>[] _keyValues; + private readonly KeyValuePair<IAsyncLocal, object?>[] _keyValues; internal MultiElementAsyncLocalValueMap(int count) { Debug.Assert(count <= MaxMultiElements); - _keyValues = new KeyValuePair<IAsyncLocal, object>[count]; + _keyValues = new KeyValuePair<IAsyncLocal, object?>[count]; } - internal void UnsafeStore(int index, IAsyncLocal key, object value) + internal void UnsafeStore(int index, IAsyncLocal key, object? value) { Debug.Assert(index < _keyValues.Length); - _keyValues[index] = new KeyValuePair<IAsyncLocal, object>(key, value); + _keyValues[index] = new KeyValuePair<IAsyncLocal, object?>(key, value); } - public IAsyncLocalValueMap Set(IAsyncLocal key, object value, bool treatNullValueAsNonexistent) + public IAsyncLocalValueMap Set(IAsyncLocal key, object? value, bool treatNullValueAsNonexistent) { // Find the key in this map. for (int i = 0; i < _keyValues.Length; i++) @@ -360,7 +361,7 @@ namespace System.Threading // overwriting the old. var multi = new MultiElementAsyncLocalValueMap(_keyValues.Length); Array.Copy(_keyValues, 0, multi._keyValues, 0, _keyValues.Length); - multi._keyValues[i] = new KeyValuePair<IAsyncLocal, object>(key, value); + multi._keyValues[i] = new KeyValuePair<IAsyncLocal, object?>(key, value); return multi; } else if (_keyValues.Length == 4) @@ -399,13 +400,13 @@ namespace System.Threading { var multi = new MultiElementAsyncLocalValueMap(_keyValues.Length + 1); Array.Copy(_keyValues, 0, multi._keyValues, 0, _keyValues.Length); - multi._keyValues[_keyValues.Length] = new KeyValuePair<IAsyncLocal, object>(key, value); + multi._keyValues[_keyValues.Length] = new KeyValuePair<IAsyncLocal, object?>(key, value); return multi; } // Otherwise, upgrade to a many map. var many = new ManyElementAsyncLocalValueMap(MaxMultiElements + 1); - foreach (KeyValuePair<IAsyncLocal, object> pair in _keyValues) + foreach (KeyValuePair<IAsyncLocal, object?> pair in _keyValues) { many[pair.Key] = pair.Value; } @@ -413,9 +414,9 @@ namespace System.Threading return many; } - public bool TryGetValue(IAsyncLocal key, out object value) + public bool TryGetValue(IAsyncLocal key, out object? value) { - foreach (KeyValuePair<IAsyncLocal, object> pair in _keyValues) + foreach (KeyValuePair<IAsyncLocal, object?> pair in _keyValues) { if (ReferenceEquals(key, pair.Key)) { @@ -429,11 +430,11 @@ namespace System.Threading } // Instance with any number of key/value pairs. - private sealed class ManyElementAsyncLocalValueMap : Dictionary<IAsyncLocal, object>, IAsyncLocalValueMap + private sealed class ManyElementAsyncLocalValueMap : Dictionary<IAsyncLocal, object?>, IAsyncLocalValueMap { public ManyElementAsyncLocalValueMap(int capacity) : base(capacity) { } - public IAsyncLocalValueMap Set(IAsyncLocal key, object value, bool treatNullValueAsNonexistent) + public IAsyncLocalValueMap Set(IAsyncLocal key, object? value, bool treatNullValueAsNonexistent) { int count = Count; bool containsKey = ContainsKey(key); @@ -443,7 +444,7 @@ namespace System.Threading if (value != null || !treatNullValueAsNonexistent) { var map = new ManyElementAsyncLocalValueMap(count + (containsKey ? 0 : 1)); - foreach (KeyValuePair<IAsyncLocal, object> pair in this) + foreach (KeyValuePair<IAsyncLocal, object?> pair in this) { map[pair.Key] = pair.Value; } @@ -477,7 +478,7 @@ namespace System.Threading else { var map = new ManyElementAsyncLocalValueMap(count - 1); - foreach (KeyValuePair<IAsyncLocal, object> pair in this) + foreach (KeyValuePair<IAsyncLocal, object?> pair in this) { if (!ReferenceEquals(key, pair.Key)) { diff --git a/src/System.Private.CoreLib/shared/System/Threading/AutoResetEvent.cs b/src/System.Private.CoreLib/shared/System/Threading/AutoResetEvent.cs index 8320d7ad5a..b8418a94bb 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/AutoResetEvent.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/AutoResetEvent.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { public sealed class AutoResetEvent : EventWaitHandle diff --git a/src/System.Private.CoreLib/shared/System/Threading/CancellationToken.cs b/src/System.Private.CoreLib/shared/System/Threading/CancellationToken.cs index 5402749d48..98b3ba2bb4 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/CancellationToken.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/CancellationToken.cs @@ -2,8 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; -using System.Runtime.CompilerServices; namespace System.Threading { @@ -33,10 +33,14 @@ namespace System.Threading // The backing TokenSource. // if null, it implicitly represents the same thing as new CancellationToken(false). // When required, it will be instantiated to reflect this. - private readonly CancellationTokenSource _source; + private readonly CancellationTokenSource? _source; //!! warning. If more fields are added, the assumptions in CreateLinkedToken may no longer be valid - private readonly static Action<object> s_actionToActionObjShunt = obj => ((Action)obj)(); + private readonly static Action<object?> s_actionToActionObjShunt = obj => + { + Debug.Assert(obj is Action, $"Expected {typeof(Action)}, got {obj}"); + ((Action)obj)(); + }; /// <summary> /// Returns an empty CancellationToken value. @@ -96,7 +100,7 @@ namespace System.Threading /// <summary> /// Internal constructor only a CancellationTokenSource should create a CancellationToken /// </summary> - internal CancellationToken(CancellationTokenSource source) => _source = source; + internal CancellationToken(CancellationTokenSource? source) => _source = source; /// <summary> /// Initializes the <see cref="T:System.Threading.CancellationToken">CancellationToken</see>. @@ -189,7 +193,7 @@ namespace System.Threading /// <returns>The <see cref="T:System.Threading.CancellationTokenRegistration"/> instance that can /// be used to unregister the callback.</returns> /// <exception cref="T:System.ArgumentNullException"><paramref name="callback"/> is null.</exception> - public CancellationTokenRegistration Register(Action<object> callback, object state) => + public CancellationTokenRegistration Register(Action<object?> callback, object? state) => Register(callback, state, useSynchronizationContext: false, useExecutionContext: true); /// <summary> @@ -217,7 +221,7 @@ namespace System.Threading /// <exception cref="T:System.ArgumentNullException"><paramref name="callback"/> is null.</exception> /// <exception cref="T:System.ObjectDisposedException">The associated <see /// cref="T:System.Threading.CancellationTokenSource">CancellationTokenSource</see> has been disposed.</exception> - public CancellationTokenRegistration Register(Action<object> callback, object state, bool useSynchronizationContext) => + public CancellationTokenRegistration Register(Action<object?> callback, object? state, bool useSynchronizationContext) => Register(callback, state, useSynchronizationContext, useExecutionContext: true); /// <summary> @@ -239,7 +243,7 @@ namespace System.Threading /// <returns>The <see cref="T:System.Threading.CancellationTokenRegistration"/> instance that can /// be used to unregister the callback.</returns> /// <exception cref="T:System.ArgumentNullException"><paramref name="callback"/> is null.</exception> - public CancellationTokenRegistration UnsafeRegister(Action<object> callback, object state) => + public CancellationTokenRegistration UnsafeRegister(Action<object?> callback, object? state) => Register(callback, state, useSynchronizationContext: false, useExecutionContext: false); /// <summary> @@ -263,12 +267,12 @@ namespace System.Threading /// <exception cref="T:System.ArgumentNullException"><paramref name="callback"/> is null.</exception> /// <exception cref="T:System.ObjectDisposedException">The associated <see /// cref="T:System.Threading.CancellationTokenSource">CancellationTokenSource</see> has been disposed.</exception> - private CancellationTokenRegistration Register(Action<object> callback, object state, bool useSynchronizationContext, bool useExecutionContext) + private CancellationTokenRegistration Register(Action<object?> callback, object? state, bool useSynchronizationContext, bool useExecutionContext) { if (callback == null) throw new ArgumentNullException(nameof(callback)); - CancellationTokenSource source = _source; + CancellationTokenSource? source = _source; return source != null ? source.InternalRegister(callback, state, useSynchronizationContext ? SynchronizationContext.Current : null, useExecutionContext ? ExecutionContext.Capture() : null) : default; // Nothing to do for tokens than can never reach the canceled state. Give back a dummy registration. @@ -296,7 +300,7 @@ namespace System.Threading /// from public CancellationToken constructors and their <see cref="IsCancellationRequested"/> values are equal.</returns> /// <exception cref="T:System.ObjectDisposedException">An associated <see /// cref="T:System.Threading.CancellationTokenSource">CancellationTokenSource</see> has been disposed.</exception> - public override bool Equals(object other) => other is CancellationToken && Equals((CancellationToken)other); + public override bool Equals(object? other) => other is CancellationToken && Equals((CancellationToken)other); /// <summary> /// Serves as a hash function for a <see cref="T:System.Threading.CancellationToken">CancellationToken</see>. diff --git a/src/System.Private.CoreLib/shared/System/Threading/CancellationTokenRegistration.cs b/src/System.Private.CoreLib/shared/System/Threading/CancellationTokenRegistration.cs index bab2ce9c03..edb29e03aa 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/CancellationTokenRegistration.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/CancellationTokenRegistration.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Threading.Tasks; namespace System.Threading @@ -147,7 +148,7 @@ namespace System.Threading /// they both refer to the output of a single call to the same Register method of a /// <see cref="T:System.Threading.CancellationToken">CancellationToken</see>. /// </returns> - public override bool Equals(object obj) => obj is CancellationTokenRegistration && Equals((CancellationTokenRegistration)obj); + public override bool Equals(object? obj) => obj is CancellationTokenRegistration && Equals((CancellationTokenRegistration)obj); /// <summary> /// Determines whether the current <see cref="T:System.Threading.CancellationToken">CancellationToken</see> instance is equal to the diff --git a/src/System.Private.CoreLib/shared/System/Threading/CancellationTokenSource.cs b/src/System.Private.CoreLib/shared/System/Threading/CancellationTokenSource.cs index 8c4dd01c3d..4d01cd09ff 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/CancellationTokenSource.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/CancellationTokenSource.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; @@ -30,7 +31,10 @@ namespace System.Threading /// <summary>Delegate used with <see cref="Timer"/> to trigger cancellation of a <see cref="CancellationTokenSource"/>.</summary> private static readonly TimerCallback s_timerCallback = obj => + { + Debug.Assert(obj is CancellationTokenSource, $"Expected {typeof(CancellationTokenSource)}, got {obj}"); ((CancellationTokenSource)obj).NotifyCancellation(throwOnFirstException: false); // skip ThrowIfDisposed() check in Cancel() + }; /// <summary>The number of callback partitions to use in a <see cref="CancellationTokenSource"/>. Must be a power of 2.</summary> private static readonly int s_numPartitions = GetPartitionCount(); @@ -49,11 +53,11 @@ namespace System.Threading /// <summary>Tracks the running callback to assist ctr.Dispose() to wait for the target callback to complete.</summary> private long _executingCallbackId; /// <summary>Partitions of callbacks. Split into multiple partitions to help with scalability of registering/unregistering; each is protected by its own lock.</summary> - private volatile CallbackPartition[] _callbackPartitions; + private volatile CallbackPartition?[]? _callbackPartitions; /// <summary>TimerQueueTimer used by CancelAfter and Timer-related ctors. Used instead of Timer to avoid extra allocations and because the rooted behavior is desired.</summary> - private volatile TimerQueueTimer _timer; + private volatile TimerQueueTimer? _timer; /// <summary><see cref="System.Threading.WaitHandle"/> lazily initialized and returned from <see cref="WaitHandle"/>.</summary> - private volatile ManualResetEvent _kernelEvent; + private volatile ManualResetEvent? _kernelEvent; /// <summary>Whether this <see cref="CancellationTokenSource"/> has been disposed.</summary> private bool _disposed; @@ -129,10 +133,10 @@ namespace System.Threading // 2. if IsCancellationRequested = false, then NotifyCancellation will see that the event exists, and will call Set(). if (IsCancellationRequested) { - _kernelEvent.Set(); + _kernelEvent!.Set(); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } - return _kernelEvent; + return _kernelEvent!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } } @@ -355,7 +359,7 @@ namespace System.Threading // expired and Disposed itself). But this would be considered bad behavior, as // Dispose() is not thread-safe and should not be called concurrently with CancelAfter(). - TimerQueueTimer timer = _timer; + TimerQueueTimer? timer = _timer; if (timer == null) { // Lazily initialize the timer in a thread-safe fashion. @@ -363,7 +367,7 @@ namespace System.Threading // chance on a timer "losing" the initialization and then // cancelling the token before it (the timer) can be disposed. timer = new TimerQueueTimer(s_timerCallback, this, Timeout.UnsignedInfinite, Timeout.UnsignedInfinite, flowExecutionContext: false); - TimerQueueTimer currentTimer = Interlocked.CompareExchange(ref _timer, timer, null); + TimerQueueTimer? currentTimer = Interlocked.CompareExchange(ref _timer, timer, null); if (currentTimer != null) { // We did not initialize the timer. Dispose the new timer. @@ -426,7 +430,7 @@ namespace System.Threading // internal source of cancellation, then Disposes of that linked source, which could // happen at the same time the external entity is requesting cancellation). - TimerQueueTimer timer = _timer; + TimerQueueTimer? timer = _timer; if (timer != null) { _timer = null; @@ -442,7 +446,7 @@ namespace System.Threading // transitioned to and while it's in the NotifyingState. if (_kernelEvent != null) { - ManualResetEvent mre = Interlocked.Exchange(ref _kernelEvent, null); + ManualResetEvent? mre = Interlocked.Exchange<ManualResetEvent?>(ref _kernelEvent!, null); if (mre != null && _state != NotifyingState) { mre.Dispose(); @@ -471,7 +475,7 @@ namespace System.Threading /// callback will have been run by the time this method returns. /// </summary> internal CancellationTokenRegistration InternalRegister( - Action<object> callback, object stateForCallback, SynchronizationContext syncContext, ExecutionContext executionContext) + Action<object?> callback, object? stateForCallback, SynchronizationContext? syncContext, ExecutionContext? executionContext) { Debug.Assert(this != s_neverCanceledSource, "This source should never be exposed via a CancellationToken."); @@ -493,7 +497,7 @@ namespace System.Threading } // Get the partitions... - CallbackPartition[] partitions = _callbackPartitions; + CallbackPartition?[]? partitions = _callbackPartitions; if (partitions == null) { partitions = new CallbackPartition[s_numPartitions]; @@ -503,7 +507,7 @@ namespace System.Threading // ...and determine which partition to use. int partitionIndex = Environment.CurrentManagedThreadId & s_numPartitionsMask; Debug.Assert(partitionIndex < partitions.Length, $"Expected {partitionIndex} to be less than {partitions.Length}"); - CallbackPartition partition = partitions[partitionIndex]; + CallbackPartition? partition = partitions[partitionIndex]; if (partition == null) { partition = new CallbackPartition(this); @@ -512,7 +516,7 @@ namespace System.Threading // Store the callback information into the callback arrays. long id; - CallbackNode node; + CallbackNode? node; bool lockTaken = false; partition.Lock.Enter(ref lockTaken); try @@ -576,7 +580,7 @@ namespace System.Threading if (!IsCancellationRequested && Interlocked.CompareExchange(ref _state, NotifyingState, NotCanceledState) == NotCanceledState) { // Dispose of the timer, if any. Dispose may be running concurrently here, but TimerQueueTimer.Close is thread-safe. - TimerQueueTimer timer = _timer; + TimerQueueTimer? timer = _timer; if (timer != null) { _timer = null; @@ -609,20 +613,20 @@ namespace System.Threading // If there are no callbacks to run, we can safely exit. Any race conditions to lazy initialize it // will see IsCancellationRequested and will then run the callback themselves. - CallbackPartition[] partitions = Interlocked.Exchange(ref _callbackPartitions, null); + CallbackPartition?[]? partitions = Interlocked.Exchange(ref _callbackPartitions, null); if (partitions == null) { Interlocked.Exchange(ref _state, NotifyingCompleteState); return; } - List<Exception> exceptionList = null; + List<Exception>? exceptionList = null; try { // For each partition, and each callback in that partition, execute the associated handler. // We call the delegates in LIFO order on each partition so that callbacks fire 'deepest first'. // This is intended to help with nesting scenarios so that child enlisters cancel before their parents. - foreach (CallbackPartition partition in partitions) + foreach (CallbackPartition? partition in partitions) { if (partition == null) { @@ -635,7 +639,7 @@ namespace System.Threading // to still be effective even as other registrations are being invoked. while (true) { - CallbackNode node; + CallbackNode? node; bool lockTaken = false; partition.Lock.Enter(ref lockTaken); try @@ -678,7 +682,7 @@ namespace System.Threading // Transition to the target syncContext and continue there. node.SynchronizationContext.Send(s => { - var n = (CallbackNode)s; + var n = (CallbackNode)s!; n.Partition.Source.ThreadIDExecutingCallbacks = Environment.CurrentManagedThreadId; n.ExecuteCallback(); }, node); @@ -819,6 +823,7 @@ namespace System.Threading // this work with a callback mechanism will add additional cost to other more common cases. return new ValueTask(Task.Factory.StartNew(s => { + Debug.Assert(s is Tuple<CancellationTokenSource, long>); var state = (Tuple<CancellationTokenSource, long>)s; state.Item1.WaitForCallbackToComplete(state.Item2); }, Tuple.Create(this, id), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default)); @@ -871,9 +876,12 @@ namespace System.Threading private sealed class LinkedNCancellationTokenSource : CancellationTokenSource { - internal static readonly Action<object> s_linkedTokenCancelDelegate = - s => ((CancellationTokenSource)s).NotifyCancellation(throwOnFirstException: false); // skip ThrowIfDisposed() check in Cancel() - private CancellationTokenRegistration[] _linkingRegistrations; + internal static readonly Action<object?> s_linkedTokenCancelDelegate = s => + { + Debug.Assert(s is CancellationTokenSource, $"Expected {typeof(CancellationTokenSource)}, got {s}"); + ((CancellationTokenSource)s).NotifyCancellation(throwOnFirstException: false); // skip ThrowIfDisposed() check in Cancel() + }; + private CancellationTokenRegistration[]? _linkingRegistrations; internal LinkedNCancellationTokenSource(params CancellationToken[] tokens) { @@ -898,7 +906,7 @@ namespace System.Threading return; } - CancellationTokenRegistration[] linkingRegistrations = _linkingRegistrations; + CancellationTokenRegistration[]? linkingRegistrations = _linkingRegistrations; if (linkingRegistrations != null) { _linkingRegistrations = null; // release for GC once we're done enumerating @@ -919,9 +927,9 @@ namespace System.Threading /// <summary>Lock that protects all state in the partition.</summary> public SpinLock Lock = new SpinLock(enableThreadOwnerTracking: false); // mutable struct; do not make this readonly /// <summary>Doubly-linked list of callbacks registered with the partition. Callbacks are removed during unregistration and as they're invoked.</summary> - public CallbackNode Callbacks; + public CallbackNode? Callbacks; /// <summary>Singly-linked list of free nodes that can be used for subsequent callback registrations.</summary> - public CallbackNode FreeNodeList; + public CallbackNode? FreeNodeList; /// <summary>Every callback is assigned a unique, never-reused ID. This defines the next available ID.</summary> public long NextAvailableId = 1; // avoid using 0, as that's the default long value and used to represent an empty node @@ -995,14 +1003,14 @@ namespace System.Threading internal sealed class CallbackNode { public readonly CallbackPartition Partition; - public CallbackNode Prev; - public CallbackNode Next; + public CallbackNode? Prev; + public CallbackNode? Next; public long Id; - public Action<object> Callback; - public object CallbackState; - public ExecutionContext ExecutionContext; - public SynchronizationContext SynchronizationContext; + public Action<object?>? Callback; + public object? CallbackState; + public ExecutionContext? ExecutionContext; + public SynchronizationContext? SynchronizationContext; public CallbackNode(CallbackPartition partition) { @@ -1012,17 +1020,21 @@ namespace System.Threading public void ExecuteCallback() { - ExecutionContext context = ExecutionContext; + ExecutionContext? context = ExecutionContext; if (context != null) { ExecutionContext.RunInternal(context, s => { + Debug.Assert(s is CallbackNode, $"Expected {typeof(CallbackNode)}, got {s}"); CallbackNode n = (CallbackNode)s; + + Debug.Assert(n.Callback != null); n.Callback(n.CallbackState); }, this); } else { + Debug.Assert(Callback != null); Callback(CallbackState); } } diff --git a/src/System.Private.CoreLib/shared/System/Threading/CompressedStack.cs b/src/System.Private.CoreLib/shared/System/Threading/CompressedStack.cs index 7f209f5920..32861df822 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/CompressedStack.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/CompressedStack.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Threading @@ -32,7 +33,7 @@ namespace System.Threading return new CompressedStack(); } - public static void Run(CompressedStack compressedStack, ContextCallback callback, object state) + public static void Run(CompressedStack compressedStack, ContextCallback callback, object? state) { if (compressedStack == null) { diff --git a/src/System.Private.CoreLib/shared/System/Threading/DeferredDisposableLifetime.cs b/src/System.Private.CoreLib/shared/System/Threading/DeferredDisposableLifetime.cs index e2b1eb983b..6038a3e752 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/DeferredDisposableLifetime.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/DeferredDisposableLifetime.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Threading @@ -41,9 +42,7 @@ namespace System.Threading /// </remarks> internal struct DeferredDisposableLifetime<T> where T : class, IDeferredDisposable { - // - // _count is positive until Dispose is called, after which it's (-1 - refcount). - // + /// <summary>_count is positive until Dispose is called, after which it's (-1 - refcount).</summary> private int _count; public bool AddRef(T obj) diff --git a/src/System.Private.CoreLib/shared/System/Threading/EventResetMode.cs b/src/System.Private.CoreLib/shared/System/Threading/EventResetMode.cs index 7aac0f51eb..5de3cb5763 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/EventResetMode.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/EventResetMode.cs @@ -12,6 +12,7 @@ ** =============================================================================*/ +#nullable enable namespace System.Threading { public enum EventResetMode diff --git a/src/System.Private.CoreLib/shared/System/Threading/EventWaitHandle.Windows.cs b/src/System.Private.CoreLib/shared/System/Threading/EventWaitHandle.Windows.cs index 62b3e4f9fc..6c7b7155ac 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/EventWaitHandle.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/EventWaitHandle.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.IO; using System.Runtime.InteropServices; @@ -18,7 +19,7 @@ namespace System.Threading SafeWaitHandle = handle; } - private void CreateEventCore(bool initialState, EventResetMode mode, string name, out bool createdNew) + private void CreateEventCore(bool initialState, EventResetMode mode, string? name, out bool createdNew) { #if !PLATFORM_WINDOWS if (name != null) @@ -43,7 +44,7 @@ namespace System.Threading SafeWaitHandle = handle; } - private static OpenExistingResult OpenExistingWorker(string name, out EventWaitHandle result) + private static OpenExistingResult OpenExistingWorker(string name, out EventWaitHandle? result) { #if PLATFORM_WINDOWS if (name == null) @@ -76,7 +77,7 @@ namespace System.Threading public bool Reset() { - bool res = Interop.Kernel32.ResetEvent(SafeWaitHandle); + bool res = Interop.Kernel32.ResetEvent(SafeWaitHandle!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/2384 if (!res) throw Win32Marshal.GetExceptionForLastWin32Error(); return res; @@ -84,7 +85,7 @@ namespace System.Threading public bool Set() { - bool res = Interop.Kernel32.SetEvent(SafeWaitHandle); + bool res = Interop.Kernel32.SetEvent(SafeWaitHandle!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/2384 if (!res) throw Win32Marshal.GetExceptionForLastWin32Error(); return res; diff --git a/src/System.Private.CoreLib/shared/System/Threading/EventWaitHandle.cs b/src/System.Private.CoreLib/shared/System/Threading/EventWaitHandle.cs index 4cd733b9bd..b01bfb2131 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/EventWaitHandle.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/EventWaitHandle.cs @@ -2,7 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +#nullable enable +using System.Diagnostics; using System.IO; namespace System.Threading @@ -14,12 +15,12 @@ namespace System.Threading { } - public EventWaitHandle(bool initialState, EventResetMode mode, string name) : + public EventWaitHandle(bool initialState, EventResetMode mode, string? name) : this(initialState, mode, name, out _) { } - public EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew) + public EventWaitHandle(bool initialState, EventResetMode mode, string? name, out bool createdNew) { if (mode != EventResetMode.AutoReset && mode != EventResetMode.ManualReset) throw new ArgumentException(SR.Argument_InvalidFlag, nameof(mode)); @@ -29,7 +30,7 @@ namespace System.Threading public static EventWaitHandle OpenExisting(string name) { - EventWaitHandle result; + EventWaitHandle? result; switch (OpenExistingWorker(name, out result)) { case OpenExistingResult.NameNotFound: @@ -39,11 +40,12 @@ namespace System.Threading case OpenExistingResult.PathNotFound: throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, name)); default: + Debug.Assert(result != null, "result should be non-null on success"); return result; } } - public static bool TryOpenExisting(string name, out EventWaitHandle result) + public static bool TryOpenExisting(string name, out EventWaitHandle? result) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { return OpenExistingWorker(name, out result) == OpenExistingResult.Success; } diff --git a/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs b/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs index a82be90fb1..4b46ab3128 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs @@ -11,6 +11,7 @@ ** ===========================================================*/ +#nullable enable using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; @@ -18,7 +19,7 @@ using System.Runtime.Serialization; namespace System.Threading { - public delegate void ContextCallback(object state); + public delegate void ContextCallback(object? state); internal delegate void ContextCallback<TState>(ref TState state); @@ -27,8 +28,8 @@ namespace System.Threading internal static readonly ExecutionContext Default = new ExecutionContext(isDefault: true); internal static readonly ExecutionContext DefaultFlowSuppressed = new ExecutionContext(AsyncLocalValueMap.Empty, Array.Empty<IAsyncLocal>(), isFlowSuppressed: true); - private readonly IAsyncLocalValueMap m_localValues; - private readonly IAsyncLocal[] m_localChangeNotifications; + private readonly IAsyncLocalValueMap? m_localValues; + private readonly IAsyncLocal[]? m_localChangeNotifications; private readonly bool m_isFlowSuppressed; private readonly bool m_isDefault; @@ -39,7 +40,7 @@ namespace System.Threading private ExecutionContext( IAsyncLocalValueMap localValues, - IAsyncLocal[] localChangeNotifications, + IAsyncLocal[]? localChangeNotifications, bool isFlowSuppressed) { m_localValues = localValues; @@ -52,9 +53,9 @@ namespace System.Threading throw new PlatformNotSupportedException(); } - public static ExecutionContext Capture() + public static ExecutionContext? Capture() { - ExecutionContext executionContext = Thread.CurrentThread._executionContext; + ExecutionContext? executionContext = Thread.CurrentThread._executionContext; if (executionContext == null) { executionContext = Default; @@ -67,7 +68,7 @@ namespace System.Threading return executionContext; } - private ExecutionContext ShallowClone(bool isFlowSuppressed) + private ExecutionContext? ShallowClone(bool isFlowSuppressed) { Debug.Assert(isFlowSuppressed != m_isFlowSuppressed); @@ -84,7 +85,7 @@ namespace System.Threading public static AsyncFlowControl SuppressFlow() { Thread currentThread = Thread.CurrentThread; - ExecutionContext executionContext = currentThread._executionContext ?? Default; + ExecutionContext? executionContext = currentThread._executionContext ?? Default; if (executionContext.m_isFlowSuppressed) { throw new InvalidOperationException(SR.InvalidOperation_CannotSupressFlowMultipleTimes); @@ -100,7 +101,7 @@ namespace System.Threading public static void RestoreFlow() { Thread currentThread = Thread.CurrentThread; - ExecutionContext executionContext = currentThread._executionContext; + ExecutionContext? executionContext = currentThread._executionContext; if (executionContext == null || !executionContext.m_isFlowSuppressed) { throw new InvalidOperationException(SR.InvalidOperation_CannotRestoreUnsupressedFlow); @@ -111,7 +112,7 @@ namespace System.Threading public static bool IsFlowSuppressed() { - ExecutionContext executionContext = Thread.CurrentThread._executionContext; + ExecutionContext? executionContext = Thread.CurrentThread._executionContext; return executionContext != null && executionContext.m_isFlowSuppressed; } @@ -119,7 +120,7 @@ namespace System.Threading internal bool IsDefault => m_isDefault; - public static void Run(ExecutionContext executionContext, ContextCallback callback, object state) + public static void Run(ExecutionContext executionContext, ContextCallback callback, object? state) { // Note: ExecutionContext.Run is an extremely hot function and used by every await, ThreadPool execution, etc. if (executionContext == null) @@ -130,7 +131,7 @@ namespace System.Threading RunInternal(executionContext, callback, state); } - internal static void RunInternal(ExecutionContext executionContext, ContextCallback callback, object state) + internal static void RunInternal(ExecutionContext? executionContext, ContextCallback callback, object? state) { // Note: ExecutionContext.RunInternal is an extremely hot function and used by every await, ThreadPool execution, etc. // Note: Manual enregistering may be addressed by "Exception Handling Write Through Optimization" @@ -140,7 +141,7 @@ namespace System.Threading // Capture references to Thread Contexts Thread currentThread0 = Thread.CurrentThread; Thread currentThread = currentThread0; - ExecutionContext previousExecutionCtx0 = currentThread0._executionContext; + ExecutionContext? previousExecutionCtx0 = currentThread0._executionContext; if (previousExecutionCtx0 != null && previousExecutionCtx0.m_isDefault) { // Default is a null ExecutionContext internally @@ -151,8 +152,8 @@ namespace System.Threading // This allows us to restore them and undo any Context changes made in callback.Invoke // so that they won't "leak" back into caller. // These variables will cross EH so be forced to stack - ExecutionContext previousExecutionCtx = previousExecutionCtx0; - SynchronizationContext previousSyncCtx = currentThread0._synchronizationContext; + ExecutionContext? previousExecutionCtx = previousExecutionCtx0; + SynchronizationContext? previousSyncCtx = currentThread0._synchronizationContext; if (executionContext != null && executionContext.m_isDefault) { @@ -165,7 +166,7 @@ namespace System.Threading RestoreChangedContextToThread(currentThread0, executionContext, previousExecutionCtx0); } - ExceptionDispatchInfo edi = null; + ExceptionDispatchInfo? edi = null; try { callback.Invoke(state); @@ -179,7 +180,7 @@ namespace System.Threading } // Re-enregistrer variables post EH with 1 post-fix so they can be used in registers rather than from stack - SynchronizationContext previousSyncCtx1 = previousSyncCtx; + SynchronizationContext? previousSyncCtx1 = previousSyncCtx; Thread currentThread1 = currentThread; // The common case is that these have not changed, so avoid the cost of a write barrier if not needed. if (currentThread1._synchronizationContext != previousSyncCtx1) @@ -188,8 +189,8 @@ namespace System.Threading currentThread1._synchronizationContext = previousSyncCtx1; } - ExecutionContext previousExecutionCtx1 = previousExecutionCtx; - ExecutionContext currentExecutionCtx1 = currentThread1._executionContext; + ExecutionContext? previousExecutionCtx1 = previousExecutionCtx; + ExecutionContext? currentExecutionCtx1 = currentThread1._executionContext; if (currentExecutionCtx1 != previousExecutionCtx1) { RestoreChangedContextToThread(currentThread1, previousExecutionCtx1, currentExecutionCtx1); @@ -200,7 +201,7 @@ namespace System.Threading } // Direct copy of the above RunInternal overload, except that it passes the state into the callback strongly-typed and by ref. - internal static void RunInternal<TState>(ExecutionContext executionContext, ContextCallback<TState> callback, ref TState state) + internal static void RunInternal<TState>(ExecutionContext? executionContext, ContextCallback<TState> callback, ref TState state) { // Note: ExecutionContext.RunInternal is an extremely hot function and used by every await, ThreadPool execution, etc. // Note: Manual enregistering may be addressed by "Exception Handling Write Through Optimization" @@ -210,7 +211,7 @@ namespace System.Threading // Capture references to Thread Contexts Thread currentThread0 = Thread.CurrentThread; Thread currentThread = currentThread0; - ExecutionContext previousExecutionCtx0 = currentThread0._executionContext; + ExecutionContext? previousExecutionCtx0 = currentThread0._executionContext; if (previousExecutionCtx0 != null && previousExecutionCtx0.m_isDefault) { // Default is a null ExecutionContext internally @@ -221,8 +222,8 @@ namespace System.Threading // This allows us to restore them and undo any Context changes made in callback.Invoke // so that they won't "leak" back into caller. // These variables will cross EH so be forced to stack - ExecutionContext previousExecutionCtx = previousExecutionCtx0; - SynchronizationContext previousSyncCtx = currentThread0._synchronizationContext; + ExecutionContext? previousExecutionCtx = previousExecutionCtx0; + SynchronizationContext? previousSyncCtx = currentThread0._synchronizationContext; if (executionContext != null && executionContext.m_isDefault) { @@ -235,7 +236,7 @@ namespace System.Threading RestoreChangedContextToThread(currentThread0, executionContext, previousExecutionCtx0); } - ExceptionDispatchInfo edi = null; + ExceptionDispatchInfo? edi = null; try { callback.Invoke(ref state); @@ -249,7 +250,7 @@ namespace System.Threading } // Re-enregistrer variables post EH with 1 post-fix so they can be used in registers rather than from stack - SynchronizationContext previousSyncCtx1 = previousSyncCtx; + SynchronizationContext? previousSyncCtx1 = previousSyncCtx; Thread currentThread1 = currentThread; // The common case is that these have not changed, so avoid the cost of a write barrier if not needed. if (currentThread1._synchronizationContext != previousSyncCtx1) @@ -258,8 +259,8 @@ namespace System.Threading currentThread1._synchronizationContext = previousSyncCtx1; } - ExecutionContext previousExecutionCtx1 = previousExecutionCtx; - ExecutionContext currentExecutionCtx1 = currentThread1._executionContext; + ExecutionContext? previousExecutionCtx1 = previousExecutionCtx; + ExecutionContext? currentExecutionCtx1 = currentThread1._executionContext; if (currentExecutionCtx1 != previousExecutionCtx1) { RestoreChangedContextToThread(currentThread1, previousExecutionCtx1, currentExecutionCtx1); @@ -282,7 +283,7 @@ namespace System.Threading RestoreChangedContextToThread(threadPoolThread, contextToRestore: executionContext, currentContext: null); } - ExceptionDispatchInfo edi = null; + ExceptionDispatchInfo? edi = null; try { callback.Invoke(state); @@ -298,7 +299,7 @@ namespace System.Threading // Enregister threadPoolThread as it crossed EH, and use enregistered variable Thread currentThread = threadPoolThread; - ExecutionContext currentExecutionCtx = currentThread._executionContext; + ExecutionContext? currentExecutionCtx = currentThread._executionContext; // Restore changed SynchronizationContext back to Default currentThread._synchronizationContext = null; @@ -333,7 +334,7 @@ namespace System.Threading // ThreadPoolWorkQueue.Dispatch will handle notifications and reset EC and SyncCtx back to default } - internal static void RestoreChangedContextToThread(Thread currentThread, ExecutionContext contextToRestore, ExecutionContext currentContext) + internal static void RestoreChangedContextToThread(Thread currentThread, ExecutionContext? contextToRestore, ExecutionContext? currentContext) { Debug.Assert(currentThread == Thread.CurrentThread); Debug.Assert(contextToRestore != currentContext); @@ -352,7 +353,7 @@ namespace System.Threading [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void ResetThreadPoolThread(Thread currentThread) { - ExecutionContext currentExecutionCtx = currentThread._executionContext; + ExecutionContext? currentExecutionCtx = currentThread._executionContext; // Reset to defaults currentThread._synchronizationContext = null; @@ -376,13 +377,13 @@ namespace System.Threading Debug.Assert(Thread.CurrentThread._synchronizationContext == null, "ThreadPool thread not on Default SynchronizationContext."); } - internal static void OnValuesChanged(ExecutionContext previousExecutionCtx, ExecutionContext nextExecutionCtx) + internal static void OnValuesChanged(ExecutionContext? previousExecutionCtx, ExecutionContext? nextExecutionCtx) { Debug.Assert(previousExecutionCtx != nextExecutionCtx); // Collect Change Notifications - IAsyncLocal[] previousChangeNotifications = previousExecutionCtx?.m_localChangeNotifications; - IAsyncLocal[] nextChangeNotifications = nextExecutionCtx?.m_localChangeNotifications; + IAsyncLocal[]? previousChangeNotifications = previousExecutionCtx?.m_localChangeNotifications; + IAsyncLocal[]? nextChangeNotifications = nextExecutionCtx?.m_localChangeNotifications; // At least one side must have notifications Debug.Assert(previousChangeNotifications != null || nextChangeNotifications != null); @@ -393,13 +394,13 @@ namespace System.Threading if (previousChangeNotifications != null && nextChangeNotifications != null) { // Notifications can't exist without values - Debug.Assert(previousExecutionCtx.m_localValues != null); - Debug.Assert(nextExecutionCtx.m_localValues != null); + Debug.Assert(previousExecutionCtx!.m_localValues != null); // TODO-NULLABLE: Compiler can't see that we're only here when this is non-null + Debug.Assert(nextExecutionCtx!.m_localValues != null); // TODO-NULLABLE: Compiler can't see that we're only here when this is non-null // Both contexts have change notifications, check previousExecutionCtx first foreach (IAsyncLocal local in previousChangeNotifications) { - previousExecutionCtx.m_localValues.TryGetValue(local, out object previousValue); - nextExecutionCtx.m_localValues.TryGetValue(local, out object currentValue); + previousExecutionCtx.m_localValues.TryGetValue(local, out object? previousValue); + nextExecutionCtx.m_localValues.TryGetValue(local, out object? currentValue); if (previousValue != currentValue) { @@ -414,9 +415,9 @@ namespace System.Threading { // If the local has a value in the previous context, we already fired the event // for that local in the code above. - if (!previousExecutionCtx.m_localValues.TryGetValue(local, out object previousValue)) + if (!previousExecutionCtx.m_localValues.TryGetValue(local, out object? previousValue)) { - nextExecutionCtx.m_localValues.TryGetValue(local, out object currentValue); + nextExecutionCtx.m_localValues.TryGetValue(local, out object? currentValue); if (previousValue != currentValue) { local.OnValueChanged(previousValue, currentValue, contextChanged: true); @@ -428,11 +429,11 @@ namespace System.Threading else if (previousChangeNotifications != null) { // Notifications can't exist without values - Debug.Assert(previousExecutionCtx.m_localValues != null); + Debug.Assert(previousExecutionCtx!.m_localValues != null); // TODO-NULLABLE: Compiler can't see that we're only here when this is non-null // No current values, so just check previous against null foreach (IAsyncLocal local in previousChangeNotifications) { - previousExecutionCtx.m_localValues.TryGetValue(local, out object previousValue); + previousExecutionCtx.m_localValues.TryGetValue(local, out object? previousValue); if (previousValue != null) { local.OnValueChanged(previousValue, null, contextChanged: true); @@ -442,11 +443,11 @@ namespace System.Threading else // Implied: nextChangeNotifications != null { // Notifications can't exist without values - Debug.Assert(nextExecutionCtx.m_localValues != null); + Debug.Assert(nextExecutionCtx!.m_localValues != null); // TODO-NULLABLE: Compiler can't see that we're only here when this is non-null // No previous values, so just check current against null - foreach (IAsyncLocal local in nextChangeNotifications) + foreach (IAsyncLocal local in nextChangeNotifications!) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34665 { - nextExecutionCtx.m_localValues.TryGetValue(local, out object currentValue); + nextExecutionCtx.m_localValues.TryGetValue(local, out object? currentValue); if (currentValue != null) { local.OnValueChanged(null, currentValue, contextChanged: true); @@ -468,26 +469,31 @@ namespace System.Threading throw new InvalidOperationException(SR.InvalidOperation_NullContext); } - internal static object GetLocalValue(IAsyncLocal local) + internal static object? GetLocalValue(IAsyncLocal local) { - ExecutionContext current = Thread.CurrentThread._executionContext; + ExecutionContext? current = Thread.CurrentThread._executionContext; if (current == null) { return null; } - current.m_localValues.TryGetValue(local, out object value); + Debug.Assert(!current.IsDefault); + Debug.Assert(current.m_localValues != null, "Only the default context should have null, and we shouldn't be here on the default context"); + current.m_localValues.TryGetValue(local, out object? value); return value; } - internal static void SetLocalValue(IAsyncLocal local, object newValue, bool needChangeNotifications) + internal static void SetLocalValue(IAsyncLocal local, object? newValue, bool needChangeNotifications) { - ExecutionContext current = Thread.CurrentThread._executionContext; + ExecutionContext? current = Thread.CurrentThread._executionContext; - object previousValue = null; + object? previousValue = null; bool hadPreviousValue = false; if (current != null) { + Debug.Assert(!current.IsDefault); + Debug.Assert(current.m_localValues != null, "Only the default context should have null, and we shouldn't be here on the default context"); + hadPreviousValue = current.m_localValues.TryGetValue(local, out previousValue); } @@ -503,11 +509,14 @@ namespace System.Threading // indicates that this is the first value change for the IAsyncLocal and it needs to be registered for change // notifications. So in this case, a null value must be stored in 'm_localValues' to indicate that the IAsyncLocal // is already registered for change notifications. - IAsyncLocal[] newChangeNotifications = null; + IAsyncLocal[]? newChangeNotifications = null; IAsyncLocalValueMap newValues; bool isFlowSuppressed = false; if (current != null) { + Debug.Assert(!current.IsDefault); + Debug.Assert(current.m_localValues != null, "Only the default context should have null, and we shouldn't be here on the default context"); + isFlowSuppressed = current.m_isFlowSuppressed; newValues = current.m_localValues.Set(local, newValue, treatNullValueAsNonexistent: !needChangeNotifications); newChangeNotifications = current.m_localChangeNotifications; @@ -564,7 +573,7 @@ namespace System.Threading public struct AsyncFlowControl : IDisposable { - private Thread _thread; + private Thread? _thread; internal void Initialize(Thread currentThread) { @@ -607,7 +616,7 @@ namespace System.Threading Undo(); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { return obj is AsyncFlowControl && Equals((AsyncFlowControl)obj); } diff --git a/src/System.Private.CoreLib/shared/System/Threading/IOCompletionCallback.cs b/src/System.Private.CoreLib/shared/System/Threading/IOCompletionCallback.cs index 571ce467eb..f2ad774395 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/IOCompletionCallback.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/IOCompletionCallback.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { [CLSCompliant(false)] diff --git a/src/System.Private.CoreLib/shared/System/Threading/IThreadPoolWorkItem.cs b/src/System.Private.CoreLib/shared/System/Threading/IThreadPoolWorkItem.cs index 31cd991813..1b79a11758 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/IThreadPoolWorkItem.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/IThreadPoolWorkItem.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { /// <summary>Represents a work item that can be executed by the ThreadPool.</summary> @@ -9,4 +10,4 @@ namespace System.Threading { void Execute(); } -}
\ No newline at end of file +} diff --git a/src/System.Private.CoreLib/shared/System/Threading/LazyInitializer.cs b/src/System.Private.CoreLib/shared/System/Threading/LazyInitializer.cs index e7928b6f93..b25db6afaf 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/LazyInitializer.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/LazyInitializer.cs @@ -8,6 +8,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System.Diagnostics; namespace System.Threading @@ -47,7 +48,7 @@ namespace System.Threading /// if an object was not used and to then dispose of the object appropriately. /// </para> /// </remarks> - public static T EnsureInitialized<T>(ref T target) where T : class => + public static T EnsureInitialized<T>(ref T target) where T : class? => Volatile.Read(ref target) ?? EnsureInitializedCore(ref target); /// <summary> @@ -56,11 +57,11 @@ namespace System.Threading /// <typeparam name="T">The reference type of the reference to be initialized.</typeparam> /// <param name="target">The variable that need to be initialized</param> /// <returns>The initialized variable</returns> - private static T EnsureInitializedCore<T>(ref T target) where T : class + private static T EnsureInitializedCore<T>(ref T target) where T : class? { try { - Interlocked.CompareExchange(ref target, Activator.CreateInstance<T>(), null); + Interlocked.CompareExchange(ref target, Activator.CreateInstance<T>(), null!); // TODO-NULLABLE-GENERIC } catch (MissingMethodException) { @@ -99,7 +100,7 @@ namespace System.Threading /// if an object was not used and to then dispose of the object appropriately. /// </para> /// </remarks> - public static T EnsureInitialized<T>(ref T target, Func<T> valueFactory) where T : class => + public static T EnsureInitialized<T>(ref T target, Func<T> valueFactory) where T : class? => Volatile.Read(ref target) ?? EnsureInitializedCore(ref target, valueFactory); /// <summary> @@ -109,7 +110,7 @@ namespace System.Threading /// <param name="target">The variable that need to be initialized</param> /// <param name="valueFactory">The delegate that will be executed to initialize the target</param> /// <returns>The initialized variable</returns> - private static T EnsureInitializedCore<T>(ref T target, Func<T> valueFactory) where T : class + private static T EnsureInitializedCore<T>(ref T target, Func<T> valueFactory) where T : class? { T value = valueFactory(); if (value == null) @@ -117,7 +118,7 @@ namespace System.Threading throw new InvalidOperationException(SR.Lazy_StaticInit_InvalidOperation); } - Interlocked.CompareExchange(ref target, value, null); + Interlocked.CompareExchange(ref target, value, null!); // TODO-NULLABLE-GENERIC Debug.Assert(target != null); return target; } @@ -134,7 +135,7 @@ namespace System.Threading /// <param name="syncLock">A reference to an object used as the mutually exclusive lock for initializing /// <paramref name="target"/>. If <paramref name="syncLock"/> is null, a new object will be instantiated.</param> /// <returns>The initialized value of type <typeparamref name="T"/>.</returns> - public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object syncLock) + public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object? syncLock) { // Fast path. if (Volatile.Read(ref initialized)) @@ -156,7 +157,7 @@ namespace System.Threading /// a new object will be instantiated. /// </param> /// <returns>The initialized object.</returns> - private static T EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object syncLock) + private static T EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object? syncLock) { // Lazily initialize the lock if necessary and then double check if initialization is still required. lock (EnsureLockInitialized(ref syncLock)) @@ -193,7 +194,7 @@ namespace System.Threading /// <param name="valueFactory">The <see cref="T:System.Func{T}"/> invoked to initialize the /// reference or value.</param> /// <returns>The initialized value of type <typeparamref name="T"/>.</returns> - public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object syncLock, Func<T> valueFactory) + public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object? syncLock, Func<T> valueFactory) { // Fast path. if (Volatile.Read(ref initialized)) @@ -217,7 +218,7 @@ namespace System.Threading /// The <see cref="T:System.Func{T}"/> to invoke in order to produce the lazily-initialized value. /// </param> /// <returns>The initialized object.</returns> - private static T EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object syncLock, Func<T> valueFactory) + private static T EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object? syncLock, Func<T> valueFactory) { // Lazily initialize the lock if necessary and then double check if initialization is still required. lock (EnsureLockInitialized(ref syncLock)) @@ -241,7 +242,7 @@ namespace System.Threading /// <paramref name="target"/>. If <paramref name="syncLock"/> is null, a new object will be instantiated.</param> /// <param name="valueFactory">The <see cref="T:System.Func{T}"/> invoked to initialize the reference.</param> /// <returns>The initialized value of type <typeparamref name="T"/>.</returns> - public static T EnsureInitialized<T>(ref T target, ref object syncLock, Func<T> valueFactory) where T : class => + public static T EnsureInitialized<T>(ref T target, ref object? syncLock, Func<T> valueFactory) where T : class? => Volatile.Read(ref target) ?? EnsureInitializedCore(ref target, ref syncLock, valueFactory); /// <summary> @@ -256,7 +257,7 @@ namespace System.Threading /// The <see cref="T:System.Func{T}"/> to invoke in order to produce the lazily-initialized value. /// </param> /// <returns>The initialized object.</returns> - private static T EnsureInitializedCore<T>(ref T target, ref object syncLock, Func<T> valueFactory) where T : class + private static T EnsureInitializedCore<T>(ref T target, ref object? syncLock, Func<T> valueFactory) where T : class? { // Lazily initialize the lock if necessary and then double check if initialization is still required. lock (EnsureLockInitialized(ref syncLock)) @@ -280,9 +281,9 @@ namespace System.Threading /// <param name="syncLock">A reference to a location containing a mutual exclusive lock. If <paramref name="syncLock"/> is null, /// a new object will be instantiated.</param> /// <returns>Initialized lock object.</returns> - private static object EnsureLockInitialized(ref object syncLock) => + private static object EnsureLockInitialized(ref object? syncLock) => syncLock ?? Interlocked.CompareExchange(ref syncLock, new object(), null) ?? - syncLock; + syncLock!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } } diff --git a/src/System.Private.CoreLib/shared/System/Threading/LazyThreadSafetyMode.cs b/src/System.Private.CoreLib/shared/System/Threading/LazyThreadSafetyMode.cs index 2d13f23762..ae650824d7 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/LazyThreadSafetyMode.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/LazyThreadSafetyMode.cs @@ -8,6 +8,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable namespace System.Threading { /// <summary> diff --git a/src/System.Private.CoreLib/shared/System/Threading/LockRecursionException.cs b/src/System.Private.CoreLib/shared/System/Threading/LockRecursionException.cs index c76c7a5040..52d45af90b 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/LockRecursionException.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/LockRecursionException.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +#nullable enable using System.Runtime.Serialization; namespace System.Threading @@ -15,12 +15,12 @@ namespace System.Threading { } - public LockRecursionException(string message) + public LockRecursionException(string? message) : base(message) { } - public LockRecursionException(string message, Exception innerException) + public LockRecursionException(string? message, Exception? innerException) : base(message, innerException) { } diff --git a/src/System.Private.CoreLib/shared/System/Threading/ManualResetEvent.cs b/src/System.Private.CoreLib/shared/System/Threading/ManualResetEvent.cs index 4b8d61f960..4b7442ffaa 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ManualResetEvent.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ManualResetEvent.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { public sealed class ManualResetEvent : EventWaitHandle diff --git a/src/System.Private.CoreLib/shared/System/Threading/ManualResetEventSlim.cs b/src/System.Private.CoreLib/shared/System/Threading/ManualResetEventSlim.cs index 18eee25587..0361327279 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ManualResetEventSlim.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ManualResetEventSlim.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Threading @@ -35,10 +36,10 @@ namespace System.Threading // These are the default spin counts we use on single-proc and MP machines. private const int DEFAULT_SPIN_SP = 1; - private volatile object m_lock; + private volatile object? m_lock; // A lock used for waiting and pulsing. Lazily initialized via EnsureLockObjectCreated() - private volatile ManualResetEvent m_eventObj; // A true Win32 event used for waiting. + private volatile ManualResetEvent? m_eventObj; // A true Win32 event used for waiting. // -- State -- // //For a packed word a uint would seem better, but Interlocked.* doesn't support them as uint isn't CLS-compliant. @@ -89,6 +90,7 @@ namespace System.Threading { // Lazily initialize the event object if needed. LazyInitializeEvent(); + Debug.Assert(m_eventObj != null); } return m_eventObj; @@ -318,7 +320,7 @@ namespace System.Threading } } - ManualResetEvent eventObj = m_eventObj; + ManualResetEvent? eventObj = m_eventObj; //Design-decision: do not set the event if we are in cancellation -> better to deadlock than to wake up waiters incorrectly //It would be preferable to wake up the event and have it throw OCE. This requires MRE to implement cancellation logic @@ -562,13 +564,14 @@ namespace System.Threading cancellationToken.ThrowIfCancellationRequested(); } - // Now enter the lock and wait. + // Now enter the lock and wait. Must be created before registering the cancellation callback, + // which will try to take this lock. EnsureLockObjectCreated(); // We must register and unregister the token outside of the lock, to avoid deadlocks. using (cancellationToken.UnsafeRegister(s_cancellationTokenCallback, this)) { - lock (m_lock) + lock (m_lock!) { // Loop to cope with spurious wakeups from other waits being canceled while (!IsSet) @@ -656,7 +659,7 @@ namespace System.Threading { // We will dispose of the event object. We do this under a lock to protect // against the race condition outlined in the Set method above. - ManualResetEvent eventObj = m_eventObj; + ManualResetEvent? eventObj = m_eventObj; if (eventObj != null) { lock (eventObj) @@ -680,11 +683,11 @@ namespace System.Threading /// <summary> /// Private helper method to wake up waiters when a cancellationToken gets canceled. /// </summary> - private static Action<object> s_cancellationTokenCallback = new Action<object>(CancellationTokenCallback); - private static void CancellationTokenCallback(object obj) + private static readonly Action<object?> s_cancellationTokenCallback = new Action<object?>(CancellationTokenCallback); + private static void CancellationTokenCallback(object? obj) { - ManualResetEventSlim mre = obj as ManualResetEventSlim; - Debug.Assert(mre != null, "Expected a ManualResetEventSlim"); + Debug.Assert(obj is ManualResetEventSlim, "Expected a ManualResetEventSlim"); + ManualResetEventSlim mre = (ManualResetEventSlim)obj; Debug.Assert(mre.m_lock != null); //the lock should have been created before this callback is registered for use. lock (mre.m_lock) { diff --git a/src/System.Private.CoreLib/shared/System/Threading/Mutex.Windows.cs b/src/System.Private.CoreLib/shared/System/Threading/Mutex.Windows.cs index 26eb4fe5ab..1d14037cc3 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Mutex.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Mutex.Windows.cs @@ -2,11 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.IO; -using Microsoft.Win32; using Microsoft.Win32.SafeHandles; using System.Runtime.InteropServices; -using System.Diagnostics; namespace System.Threading { @@ -18,7 +17,7 @@ namespace System.Threading private const uint AccessRights = (uint)Interop.Kernel32.MAXIMUM_ALLOWED | Interop.Kernel32.SYNCHRONIZE | Interop.Kernel32.MUTEX_MODIFY_STATE; - private void CreateMutexCore(bool initiallyOwned, string name, out bool createdNew) + private void CreateMutexCore(bool initiallyOwned, string? name, out bool createdNew) { uint mutexFlags = initiallyOwned ? Interop.Kernel32.CREATE_MUTEX_INITIAL_OWNER : 0; SafeWaitHandle mutexHandle = Interop.Kernel32.CreateMutexEx(IntPtr.Zero, name, mutexFlags, AccessRights); @@ -42,7 +41,7 @@ namespace System.Threading SafeWaitHandle = mutexHandle; } - private static OpenExistingResult OpenExistingWorker(string name, out Mutex result) + private static OpenExistingResult OpenExistingWorker(string name, out Mutex? result) { if (name == null) { @@ -90,7 +89,7 @@ namespace System.Threading // in a Mutex's ACL is MUTEX_ALL_ACCESS (0x1F0001). public void ReleaseMutex() { - if (!Interop.Kernel32.ReleaseMutex(SafeWaitHandle)) + if (!Interop.Kernel32.ReleaseMutex(SafeWaitHandle!)) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/2384 { throw new ApplicationException(SR.Arg_SynchronizationLockException); } diff --git a/src/System.Private.CoreLib/shared/System/Threading/Mutex.cs b/src/System.Private.CoreLib/shared/System/Threading/Mutex.cs index d85242892d..45c0c30943 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Mutex.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Mutex.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.IO; using Microsoft.Win32; using Microsoft.Win32.SafeHandles; @@ -15,12 +16,12 @@ namespace System.Threading /// </summary> public sealed partial class Mutex : WaitHandle { - public Mutex(bool initiallyOwned, string name, out bool createdNew) + public Mutex(bool initiallyOwned, string? name, out bool createdNew) { CreateMutexCore(initiallyOwned, name, out createdNew); } - public Mutex(bool initiallyOwned, string name) + public Mutex(bool initiallyOwned, string? name) { CreateMutexCore(initiallyOwned, name, out _); } @@ -42,7 +43,7 @@ namespace System.Threading public static Mutex OpenExisting(string name) { - switch (OpenExistingWorker(name, out Mutex result)) + switch (OpenExistingWorker(name, out Mutex? result)) { case OpenExistingResult.NameNotFound: throw new WaitHandleCannotBeOpenedException(); @@ -52,11 +53,12 @@ namespace System.Threading throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, name)); default: + Debug.Assert(result != null, "result should be non-null on success"); return result; } } - public static bool TryOpenExisting(string name, out Mutex result) => + public static bool TryOpenExisting(string name, out Mutex? result) => // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 OpenExistingWorker(name, out result) == OpenExistingResult.Success; } } diff --git a/src/System.Private.CoreLib/shared/System/Threading/NativeOverlapped.cs b/src/System.Private.CoreLib/shared/System/Threading/NativeOverlapped.cs index 933cb81ecc..7e9d29775d 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/NativeOverlapped.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/NativeOverlapped.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; namespace System.Threading diff --git a/src/System.Private.CoreLib/shared/System/Threading/ParameterizedThreadStart.cs b/src/System.Private.CoreLib/shared/System/Threading/ParameterizedThreadStart.cs index c0f29e8e80..4f49fc1aa7 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ParameterizedThreadStart.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ParameterizedThreadStart.cs @@ -12,7 +12,8 @@ ** =============================================================================*/ +#nullable enable namespace System.Threading { - public delegate void ParameterizedThreadStart(object obj); + public delegate void ParameterizedThreadStart(object? obj); } diff --git a/src/System.Private.CoreLib/shared/System/Threading/ReaderWriterLockSlim.cs b/src/System.Private.CoreLib/shared/System/Threading/ReaderWriterLockSlim.cs index 9776871b3b..f25c08d64b 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ReaderWriterLockSlim.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ReaderWriterLockSlim.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; // for TraceInformation using System.Runtime.CompilerServices; @@ -40,7 +41,7 @@ namespace System.Threading public int upgradecount; // Next RWC in this thread's list. - public ReaderWriterCount next; + public ReaderWriterCount? next; } /// <summary> @@ -74,10 +75,10 @@ namespace System.Threading private int _writeLockOwnerId; // conditions we wait on. - private EventWaitHandle _writeEvent; // threads waiting to acquire a write lock go here. - private EventWaitHandle _readEvent; // threads waiting to acquire a read lock go here (will be released in bulk) - private EventWaitHandle _upgradeEvent; // thread waiting to acquire the upgrade lock - private EventWaitHandle _waitUpgradeEvent; // thread waiting to upgrade from the upgrade lock to a write lock go here (at most one) + private EventWaitHandle? _writeEvent; // threads waiting to acquire a write lock go here. + private EventWaitHandle? _readEvent; // threads waiting to acquire a read lock go here (will be released in bulk) + private EventWaitHandle? _upgradeEvent; // thread waiting to acquire the upgrade lock + private EventWaitHandle? _waitUpgradeEvent; // thread waiting to upgrade from the upgrade lock to a write lock go here (at most one) // Every lock instance has a unique ID, which is used by ReaderWriterCount to associate itself with the lock // without holding a reference to it. @@ -86,7 +87,7 @@ namespace System.Threading // See comments on ReaderWriterCount. [ThreadStatic] - private static ReaderWriterCount t_rwc; + private static ReaderWriterCount? t_rwc; private bool _fUpgradeThreadHoldingRead; @@ -195,10 +196,10 @@ namespace System.Threading /// could not be found. /// </summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] - private ReaderWriterCount GetThreadRWCount(bool dontAllocate) + private ReaderWriterCount? GetThreadRWCount(bool dontAllocate) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { - ReaderWriterCount rwc = t_rwc; - ReaderWriterCount empty = null; + ReaderWriterCount? rwc = t_rwc; + ReaderWriterCount? empty = null; while (rwc != null) { if (rwc.lockID == _lockID) @@ -305,7 +306,7 @@ namespace System.Threading if (_fDisposed) throw new ObjectDisposedException(null); - ReaderWriterCount lrwc = null; + ReaderWriterCount lrwc; int id = Environment.CurrentManagedThreadId; if (!_fIsReentrant) @@ -318,7 +319,7 @@ namespace System.Threading _spinLock.Enter(EnterSpinLockReason.EnterAnyRead); - lrwc = GetThreadRWCount(false); + lrwc = GetThreadRWCount(dontAllocate: false)!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 //Check if the reader lock is already acquired. Note, we could //check the presence of a reader by not allocating rwc (But that @@ -343,7 +344,7 @@ namespace System.Threading else { _spinLock.Enter(EnterSpinLockReason.EnterAnyRead); - lrwc = GetThreadRWCount(false); + lrwc = GetThreadRWCount(dontAllocate: false)!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 if (lrwc.readercount > 0) { lrwc.readercount++; @@ -401,7 +402,7 @@ namespace System.Threading _spinLock.Enter(EnterSpinLockReason.EnterAnyRead); //The per-thread structure may have been recycled as the lock is acquired (due to message pumping), load again. if (IsRwHashEntryChanged(lrwc)) - lrwc = GetThreadRWCount(false); + lrwc = GetThreadRWCount(dontAllocate: false)!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 continue; } @@ -410,7 +411,7 @@ namespace System.Threading { LazyCreateEvent(ref _readEvent, EnterLockType.Read); if (IsRwHashEntryChanged(lrwc)) - lrwc = GetThreadRWCount(false); + lrwc = GetThreadRWCount(dontAllocate: false)!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 continue; // since we left the lock, start over. } @@ -420,7 +421,7 @@ namespace System.Threading return false; } if (IsRwHashEntryChanged(lrwc)) - lrwc = GetThreadRWCount(false); + lrwc = GetThreadRWCount(dontAllocate: false)!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } _spinLock.Exit(); @@ -453,7 +454,7 @@ namespace System.Threading throw new ObjectDisposedException(null); int id = Environment.CurrentManagedThreadId; - ReaderWriterCount lrwc; + ReaderWriterCount? lrwc; bool upgradingToWrite = false; if (!_fIsReentrant) @@ -476,7 +477,7 @@ namespace System.Threading } _spinLock.Enter(enterMyLockReason); - lrwc = GetThreadRWCount(true); + lrwc = GetThreadRWCount(dontAllocate: true); //Can't acquire write lock with reader lock held. if (lrwc != null && lrwc.readercount > 0) @@ -502,7 +503,7 @@ namespace System.Threading } _spinLock.Enter(enterMyLockReason); - lrwc = GetThreadRWCount(false); + lrwc = GetThreadRWCount(dontAllocate: false)!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 if (id == _writeLockOwnerId) { @@ -555,7 +556,7 @@ namespace System.Threading if (lrwc != null) { if (IsRwHashEntryChanged(lrwc)) - lrwc = GetThreadRWCount(false); + lrwc = GetThreadRWCount(dontAllocate: false)!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 if (lrwc.readercount > 0) { @@ -622,8 +623,9 @@ namespace System.Threading if (_fIsReentrant) { + Debug.Assert(lrwc != null, "Initialized based on _fIsReentrant earlier in the method"); if (IsRwHashEntryChanged(lrwc)) - lrwc = GetThreadRWCount(false); + lrwc = GetThreadRWCount(dontAllocate: false)!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 lrwc.writercount++; } @@ -660,7 +662,7 @@ namespace System.Threading throw new ObjectDisposedException(null); int id = Environment.CurrentManagedThreadId; - ReaderWriterCount lrwc; + ReaderWriterCount? lrwc; if (!_fIsReentrant) { @@ -676,7 +678,7 @@ namespace System.Threading } _spinLock.Enter(EnterSpinLockReason.EnterAnyRead); - lrwc = GetThreadRWCount(true); + lrwc = GetThreadRWCount(dontAllocate: true); //Can't acquire upgrade lock with reader lock held. if (lrwc != null && lrwc.readercount > 0) { @@ -687,7 +689,7 @@ namespace System.Threading else { _spinLock.Enter(EnterSpinLockReason.EnterAnyRead); - lrwc = GetThreadRWCount(false); + lrwc = GetThreadRWCount(dontAllocate: false)!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 if (id == _upgradeLockOwnerId) { @@ -764,8 +766,9 @@ namespace System.Threading { //The lock may have been dropped getting here, so make a quick check to see whether some other //thread did not grab the entry. + Debug.Assert(lrwc != null, "Initialized based on _fIsReentrant earlier in the method"); if (IsRwHashEntryChanged(lrwc)) - lrwc = GetThreadRWCount(false); + lrwc = GetThreadRWCount(dontAllocate: false)!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 lrwc.upgradecount++; } @@ -776,11 +779,9 @@ namespace System.Threading public void ExitReadLock() { - ReaderWriterCount lrwc = null; - _spinLock.Enter(EnterSpinLockReason.ExitAnyRead); - lrwc = GetThreadRWCount(true); + ReaderWriterCount? lrwc = GetThreadRWCount(dontAllocate: true); if (lrwc == null || lrwc.readercount < 1) { @@ -829,7 +830,7 @@ namespace System.Threading else { _spinLock.Enter(EnterSpinLockReason.ExitAnyWrite); - lrwc = GetThreadRWCount(false); + lrwc = GetThreadRWCount(dontAllocate: false)!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 if (lrwc == null) { @@ -863,7 +864,7 @@ namespace System.Threading public void ExitUpgradeableReadLock() { - ReaderWriterCount lrwc; + ReaderWriterCount? lrwc; if (!_fIsReentrant) { if (Environment.CurrentManagedThreadId != _upgradeLockOwnerId) @@ -876,7 +877,7 @@ namespace System.Threading else { _spinLock.Enter(EnterSpinLockReason.ExitAnyRead); - lrwc = GetThreadRWCount(true); + lrwc = GetThreadRWCount(dontAllocate: true); if (lrwc == null) { @@ -913,7 +914,7 @@ namespace System.Threading /// while holding a spin lock). If all goes well, reenter the lock and /// set 'waitEvent' /// </summary> - private void LazyCreateEvent(ref EventWaitHandle waitEvent, EnterLockType enterLockType) + private void LazyCreateEvent(ref EventWaitHandle? waitEvent, EnterLockType enterLockType) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { #if DEBUG Debug.Assert(_spinLock.IsHeld); @@ -1098,7 +1099,7 @@ namespace System.Threading if (_numWriteUpgradeWaiters > 0 && _fUpgradeThreadHoldingRead && readercount == 2) { _spinLock.Exit(); // Exit before signaling to improve efficiency (wakee will need the lock) - _waitUpgradeEvent.Set(); // release all upgraders (however there can be at most one). + _waitUpgradeEvent!.Set(); // release all upgraders (however there can be at most one). Known non-null because _numWriteUpgradeWaiters > 0. return; } } @@ -1107,10 +1108,10 @@ namespace System.Threading { //We have to be careful now, as we are dropping the lock. //No new writes should be allowed to sneak in if an upgrade - //was pending. + //was pending. _spinLock.Exit(); // Exit before signaling to improve efficiency (wakee will need the lock) - _waitUpgradeEvent.Set(); // release all upgraders (however there can be at most one). + _waitUpgradeEvent!.Set(); // release all upgraders (however there can be at most one). Known non-null because _numWriteUpgradeWaiters > 0. } else if (readercount == 0 && _numWriteWaiters > 0) { @@ -1126,7 +1127,7 @@ namespace System.Threading if (signaled == WaiterStates.None) { - _writeEvent.Set(); // release one writer. + _writeEvent!.Set(); // release one writer. Known non-null because _numWriteWaiters > 0. } } else @@ -1168,10 +1169,10 @@ namespace System.Threading _spinLock.Exit(); // Exit before signaling to improve efficiency (wakee will need the lock) if (setReadEvent) - _readEvent.Set(); // release all readers. + _readEvent!.Set(); // release all readers. Known non-null because _numUpgradeWaiters != 0. if (setUpgradeEvent) - _upgradeEvent.Set(); //release one upgrader. + _upgradeEvent!.Set(); //release one upgrader. } private bool IsWriterAcquired() @@ -1364,7 +1365,7 @@ namespace System.Threading get { int count = 0; - ReaderWriterCount lrwc = GetThreadRWCount(true); + ReaderWriterCount? lrwc = GetThreadRWCount(dontAllocate: true); if (lrwc != null) count = lrwc.readercount; @@ -1380,7 +1381,7 @@ namespace System.Threading { int count = 0; - ReaderWriterCount lrwc = GetThreadRWCount(true); + ReaderWriterCount? lrwc = GetThreadRWCount(dontAllocate: true); if (lrwc != null) count = lrwc.upgradecount; @@ -1404,7 +1405,7 @@ namespace System.Threading { int count = 0; - ReaderWriterCount lrwc = GetThreadRWCount(true); + ReaderWriterCount? lrwc = GetThreadRWCount(dontAllocate: true); if (lrwc != null) count = lrwc.writercount; diff --git a/src/System.Private.CoreLib/shared/System/Threading/Semaphore.Windows.cs b/src/System.Private.CoreLib/shared/System/Threading/Semaphore.Windows.cs index 8a14f5ef38..f5c2610e10 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Semaphore.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Semaphore.Windows.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Microsoft.Win32.SafeHandles; using System.Diagnostics; using System.IO; @@ -18,7 +19,7 @@ namespace System.Threading SafeWaitHandle = handle; } - private void CreateSemaphoreCore(int initialCount, int maximumCount, string name, out bool createdNew) + private void CreateSemaphoreCore(int initialCount, int maximumCount, string? name, out bool createdNew) { Debug.Assert(initialCount >= 0); Debug.Assert(maximumCount >= 1); @@ -43,7 +44,7 @@ namespace System.Threading this.SafeWaitHandle = myHandle; } - private static OpenExistingResult OpenExistingWorker(string name, out Semaphore result) + private static OpenExistingResult OpenExistingWorker(string name, out Semaphore? result) { #if PLATFORM_WINDOWS if (name == null) @@ -79,7 +80,7 @@ namespace System.Threading private int ReleaseCore(int releaseCount) { int previousCount; - if (!Interop.Kernel32.ReleaseSemaphore(SafeWaitHandle, releaseCount, out previousCount)) + if (!Interop.Kernel32.ReleaseSemaphore(SafeWaitHandle!, releaseCount, out previousCount)) throw new SemaphoreFullException(); return previousCount; diff --git a/src/System.Private.CoreLib/shared/System/Threading/Semaphore.cs b/src/System.Private.CoreLib/shared/System/Threading/Semaphore.cs index 6014fcd1c8..7c75db3c1b 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Semaphore.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Semaphore.cs @@ -2,8 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using Microsoft.Win32; using Microsoft.Win32.SafeHandles; +using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; @@ -15,12 +17,12 @@ namespace System.Threading // Win32 only takes maximum count of int.MaxValue public Semaphore(int initialCount, int maximumCount) : this(initialCount, maximumCount, null) { } - public Semaphore(int initialCount, int maximumCount, string name) : + public Semaphore(int initialCount, int maximumCount, string? name) : this(initialCount, maximumCount, name, out _) { } - public Semaphore(int initialCount, int maximumCount, string name, out bool createdNew) + public Semaphore(int initialCount, int maximumCount, string? name, out bool createdNew) { if (initialCount < 0) throw new ArgumentOutOfRangeException(nameof(initialCount), SR.ArgumentOutOfRange_NeedNonNegNum); @@ -36,7 +38,7 @@ namespace System.Threading public static Semaphore OpenExisting(string name) { - Semaphore result; + Semaphore? result; switch (OpenExistingWorker(name, out result)) { case OpenExistingResult.NameNotFound: @@ -46,11 +48,12 @@ namespace System.Threading case OpenExistingResult.PathNotFound: throw new IOException(SR.Format(SR.IO_PathNotFound_Path, name)); default: + Debug.Assert(result != null, "result should be non-null on success"); return result; } } - public static bool TryOpenExisting(string name, out Semaphore result) => + public static bool TryOpenExisting(string name, out Semaphore? result) => // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 OpenExistingWorker(name, out result) == OpenExistingResult.Success; public int Release() => ReleaseCore(1); diff --git a/src/System.Private.CoreLib/shared/System/Threading/SemaphoreFullException.cs b/src/System.Private.CoreLib/shared/System/Threading/SemaphoreFullException.cs index a6cff781df..5bee6108c0 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/SemaphoreFullException.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/SemaphoreFullException.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +#nullable enable using System.Runtime.Serialization; namespace System.Threading @@ -15,11 +15,11 @@ namespace System.Threading { } - public SemaphoreFullException(string message) : base(message) + public SemaphoreFullException(string? message) : base(message) { } - public SemaphoreFullException(string message, Exception innerException) : base(message, innerException) + public SemaphoreFullException(string? message, Exception? innerException) : base(message, innerException) { } diff --git a/src/System.Private.CoreLib/shared/System/Threading/SemaphoreSlim.cs b/src/System.Private.CoreLib/shared/System/Threading/SemaphoreSlim.cs index c7daceff4b..ea5bc4de7b 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/SemaphoreSlim.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/SemaphoreSlim.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Threading.Tasks; @@ -48,17 +49,17 @@ namespace System.Threading private int m_countOfWaitersPulsedToWake; // Dummy object used to in lock statements to protect the semaphore count, wait handle and cancelation - private object m_lockObj; + private object? m_lockObj; // initialized non-null, then set to null on Dispose // TODO-NULLABLE: Consider using a separate field to track disposal // Act as the semaphore wait handle, it's lazily initialized if needed, the first WaitHandle call initialize it // and wait an release sets and resets it respectively as long as it is not null - private volatile ManualResetEvent m_waitHandle; + private volatile ManualResetEvent? m_waitHandle; // Head of list representing asynchronous waits on the semaphore. - private TaskNode m_asyncHead; + private TaskNode? m_asyncHead; // Tail of list representing asynchronous waits on the semaphore. - private TaskNode m_asyncTail; + private TaskNode? m_asyncTail; // A pre-completed task with Result==true private static readonly Task<bool> s_trueTask = @@ -73,8 +74,8 @@ namespace System.Threading // Task in a linked list of asynchronous waiters private sealed class TaskNode : Task<bool> { - internal TaskNode Prev, Next; - internal TaskNode() : base((object)null, TaskCreationOptions.RunContinuationsAsynchronously) { } + internal TaskNode? Prev, Next; + internal TaskNode() : base((object?)null, TaskCreationOptions.RunContinuationsAsynchronously) { } } #endregion @@ -113,7 +114,7 @@ namespace System.Threading return m_waitHandle; //lock the count to avoid multiple threads initializing the handle if it is null - lock (m_lockObj) + lock (m_lockObj!) { if (m_waitHandle == null) { @@ -314,7 +315,7 @@ namespace System.Threading } bool waitSuccessful = false; - Task<bool> asyncWaitTask = null; + Task<bool>? asyncWaitTask = null; bool lockTaken = false; //Register for cancellation outside of the main lock. @@ -349,7 +350,7 @@ namespace System.Threading try { } finally { - Monitor.Enter(m_lockObj, ref lockTaken); + Monitor.Enter(m_lockObj!, ref lockTaken); if (lockTaken) { m_waitCount++; @@ -370,7 +371,7 @@ namespace System.Threading // If the count > 0 we are good to move on. // If not, then wait if we were given allowed some wait duration - OperationCanceledException oce = null; + OperationCanceledException? oce = null; if (m_currentCount == 0) { @@ -418,7 +419,7 @@ namespace System.Threading if (lockTaken) { m_waitCount--; - Monitor.Exit(m_lockObj); + Monitor.Exit(m_lockObj!); } // Unregister the cancellation callback. @@ -462,7 +463,7 @@ namespace System.Threading } } // ** the actual wait ** - bool waitSuccessful = Monitor.Wait(m_lockObj, remainingWaitMilliseconds); + bool waitSuccessful = Monitor.Wait(m_lockObj!, remainingWaitMilliseconds); // This waiter has woken up and this needs to be reflected in the count of waiters pulsed to wake. Since we // don't have thread-specific pulse state, there is not enough information to tell whether this thread woke up @@ -621,7 +622,7 @@ namespace System.Threading if (cancellationToken.IsCancellationRequested) return Task.FromCanceled<bool>(cancellationToken); - lock (m_lockObj) + lock (m_lockObj!) { // If there are counts available, allow this waiter to succeed. if (m_currentCount > 0) @@ -653,7 +654,7 @@ namespace System.Threading /// <returns>The created task.</returns> private TaskNode CreateAndAddAsyncWaiter() { - Debug.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held"); + Debug.Assert(Monitor.IsEntered(m_lockObj!), "Requires the lock be held"); // Create the task var task = new TaskNode(); @@ -683,7 +684,7 @@ namespace System.Threading private bool RemoveAsyncWaiter(TaskNode task) { Debug.Assert(task != null, "Expected non-null task"); - Debug.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held"); + Debug.Assert(Monitor.IsEntered(m_lockObj!), "Requires the lock be held"); // Is the task in the list? To be in the list, either it's the head or it has a predecessor that's in the list. bool wasInList = m_asyncHead == task || task.Prev != null; @@ -710,7 +711,7 @@ namespace System.Threading private async Task<bool> WaitUntilCountOrTimeoutAsync(TaskNode asyncWaiter, int millisecondsTimeout, CancellationToken cancellationToken) { Debug.Assert(asyncWaiter != null, "Waiter should have been constructed"); - Debug.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held"); + Debug.Assert(Monitor.IsEntered(m_lockObj!), "Requires the lock be held"); // Wait until either the task is completed, timeout occurs, or cancellation is requested. // We need to ensure that the Task.Delay task is appropriately cleaned up if the await @@ -732,7 +733,7 @@ namespace System.Threading // If the await completed synchronously, we still hold the lock. If it didn't, // we no longer hold the lock. As such, acquire it. - lock (m_lockObj) + lock (m_lockObj!) { // Remove the task from the list. If we're successful in doing so, // we know that no one else has tried to complete this waiter yet, @@ -783,7 +784,7 @@ namespace System.Threading } int returnCount; - lock (m_lockObj) + lock (m_lockObj!) { // Read the m_currentCount into a local variable to avoid unnecessary volatile accesses inside the lock. int currentCount = m_currentCount; @@ -817,7 +818,7 @@ namespace System.Threading m_countOfWaitersPulsedToWake += waitersToNotify; for (int i = 0; i < waitersToNotify; i++) { - Monitor.Pulse(m_lockObj); + Monitor.Pulse(m_lockObj!); } } @@ -888,7 +889,7 @@ namespace System.Threading m_waitHandle.Dispose(); m_waitHandle = null; } - m_lockObj = null; + m_lockObj = null!; m_asyncHead = null; m_asyncTail = null; } @@ -897,14 +898,14 @@ namespace System.Threading /// <summary> /// Private helper method to wake up waiters when a cancellationToken gets canceled. /// </summary> - private static Action<object> s_cancellationTokenCanceledEventHandler = new Action<object>(CancellationTokenCanceledEventHandler); - private static void CancellationTokenCanceledEventHandler(object obj) + private static readonly Action<object?> s_cancellationTokenCanceledEventHandler = new Action<object?>(CancellationTokenCanceledEventHandler); + private static void CancellationTokenCanceledEventHandler(object? obj) { - SemaphoreSlim semaphore = obj as SemaphoreSlim; - Debug.Assert(semaphore != null, "Expected a SemaphoreSlim"); - lock (semaphore.m_lockObj) + Debug.Assert(obj is SemaphoreSlim, "Expected a SemaphoreSlim"); + SemaphoreSlim semaphore = (SemaphoreSlim)obj; + lock (semaphore.m_lockObj!) { - Monitor.PulseAll(semaphore.m_lockObj); //wake up all waiters. + Monitor.PulseAll(semaphore.m_lockObj!); //wake up all waiters. } } diff --git a/src/System.Private.CoreLib/shared/System/Threading/SendOrPostCallback.cs b/src/System.Private.CoreLib/shared/System/Threading/SendOrPostCallback.cs index b96914ab2c..2257ad6b03 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/SendOrPostCallback.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/SendOrPostCallback.cs @@ -2,7 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { - public delegate void SendOrPostCallback(object state); + public delegate void SendOrPostCallback(object? state); } diff --git a/src/System.Private.CoreLib/shared/System/Threading/SpinLock.cs b/src/System.Private.CoreLib/shared/System/Threading/SpinLock.cs index 2b0610539d..1e6bcc5110 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/SpinLock.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/SpinLock.cs @@ -11,6 +11,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System.Diagnostics; using System.Runtime.CompilerServices; @@ -90,7 +91,7 @@ namespace System.Threading // The maximum number of waiters (only used if the thread tracking is disabled) // The actual maximum waiters count is this number divided by two because each waiter increments the waiters count by 2 // The waiters count is calculated by m_owner & WAITERS_MASK 01111....110 - private static int MAXIMUM_WAITERS = WAITERS_MASK; + private const int MAXIMUM_WAITERS = WAITERS_MASK; [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int CompareExchange(ref int location, int value, int comparand, ref bool success) diff --git a/src/System.Private.CoreLib/shared/System/Threading/SpinWait.cs b/src/System.Private.CoreLib/shared/System/Threading/SpinWait.cs index 6fa99e15c1..412496535e 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/SpinWait.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/SpinWait.cs @@ -8,6 +8,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System.Diagnostics; namespace System.Threading diff --git a/src/System.Private.CoreLib/shared/System/Threading/SynchronizationContext.cs b/src/System.Private.CoreLib/shared/System/Threading/SynchronizationContext.cs index 93555e9072..3f9a2bec2f 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/SynchronizationContext.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/SynchronizationContext.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { public partial class SynchronizationContext @@ -13,16 +14,16 @@ namespace System.Threading } #if !FEATURE_APPX && !ENABLE_WINRT - public static SynchronizationContext Current => Thread.CurrentThread._synchronizationContext; + public static SynchronizationContext? Current => Thread.CurrentThread._synchronizationContext; #endif protected void SetWaitNotificationRequired() => _requireWaitNotification = true; public bool IsWaitNotificationRequired() => _requireWaitNotification; - public virtual void Send(SendOrPostCallback d, object state) => d(state); + public virtual void Send(SendOrPostCallback d, object? state) => d(state); - public virtual void Post(SendOrPostCallback d, object state) => ThreadPool.QueueUserWorkItem(s => s.d(s.state), (d, state), preferLocal: false); + public virtual void Post(SendOrPostCallback d, object? state) => ThreadPool.QueueUserWorkItem(s => s.d(s.state), (d, state), preferLocal: false); /// <summary> /// Optional override for subclasses, for responding to notification that operation is starting. @@ -55,7 +56,7 @@ namespace System.Threading return WaitHandle.WaitMultipleIgnoringSyncContext(waitHandles, waitAll, millisecondsTimeout); } - public static void SetSynchronizationContext(SynchronizationContext syncContext) => Thread.CurrentThread._synchronizationContext = syncContext; + public static void SetSynchronizationContext(SynchronizationContext? syncContext) => Thread.CurrentThread._synchronizationContext = syncContext; public virtual SynchronizationContext CreateCopy() => new SynchronizationContext(); } diff --git a/src/System.Private.CoreLib/shared/System/Threading/SynchronizationLockException.cs b/src/System.Private.CoreLib/shared/System/Threading/SynchronizationLockException.cs index 3b5d31f3c0..fbd685afc9 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/SynchronizationLockException.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/SynchronizationLockException.cs @@ -12,6 +12,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System.Threading @@ -26,13 +27,13 @@ namespace System.Threading HResult = HResults.COR_E_SYNCHRONIZATIONLOCK; } - public SynchronizationLockException(string message) + public SynchronizationLockException(string? message) : base(message) { HResult = HResults.COR_E_SYNCHRONIZATIONLOCK; } - public SynchronizationLockException(string message, Exception innerException) + public SynchronizationLockException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_SYNCHRONIZATIONLOCK; diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/AsyncCausalityTracer.Noop.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/AsyncCausalityTracer.Noop.cs index b00d5d6756..927b8fa1e4 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/AsyncCausalityTracer.Noop.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/AsyncCausalityTracer.Noop.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Threading.Tasks diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/AsyncCausalityTracerConstants.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/AsyncCausalityTracerConstants.cs index 3677051f05..7e710677ce 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/AsyncCausalityTracerConstants.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/AsyncCausalityTracerConstants.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading.Tasks { internal enum AsyncCausalityStatus diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs index df7c9342f3..155b00a2f4 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs @@ -14,6 +14,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -51,9 +52,9 @@ namespace System.Threading.Tasks private int m_processingCount; /// <summary>Completion state for a task representing the completion of this pair.</summary> /// <remarks>Lazily-initialized only if the scheduler pair is shutting down or if the Completion is requested.</remarks> - private CompletionState m_completionState; + private CompletionState? m_completionState; /// <summary>Lazily-initialized work item for processing when targeting the default scheduler.</summary> - private SchedulerWorkItem m_threadPoolWorkItem; + private SchedulerWorkItem? m_threadPoolWorkItem; /// <summary>A constant value used to signal unlimited processing.</summary> private const int UNLIMITED_PROCESSING = -1; @@ -152,7 +153,7 @@ namespace System.Threading.Tasks private CompletionState EnsureCompletionStateInitialized() { // ValueLock not needed, but it's ok if it's held - return LazyInitializer.EnsureInitialized(ref m_completionState, () => new CompletionState()); + return LazyInitializer.EnsureInitialized<CompletionState>(ref m_completionState!, () => new CompletionState()); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } /// <summary>Gets whether completion has been requested.</summary> @@ -211,10 +212,11 @@ namespace System.Threading.Tasks cs.m_completionQueued = true; ThreadPool.QueueUserWorkItem(state => { + Debug.Assert(state is ConcurrentExclusiveSchedulerPair); var localThis = (ConcurrentExclusiveSchedulerPair)state; - Debug.Assert(!localThis.m_completionState.IsCompleted, "Completion should only happen once."); + Debug.Assert(!localThis.m_completionState!.IsCompleted, "Completion should only happen once."); - List<Exception> exceptions = localThis.m_completionState.m_exceptions; + List<Exception>? exceptions = localThis.m_completionState.m_exceptions; bool success = (exceptions != null && exceptions.Count > 0) ? localThis.m_completionState.TrySetException(exceptions) : localThis.m_completionState.TrySetResult(); @@ -229,7 +231,7 @@ namespace System.Threading.Tasks /// <param name="faultedTask">The faulted worker task that's initiating the shutdown.</param> private void FaultWithTask(Task faultedTask) { - Debug.Assert(faultedTask != null && faultedTask.IsFaulted && faultedTask.Exception.InnerExceptions.Count > 0, + Debug.Assert(faultedTask != null && faultedTask.IsFaulted && faultedTask.Exception!.InnerExceptions.Count > 0, "Needs a task in the faulted state and thus with exceptions."); ContractAssertMonitorStatus(ValueLock, held: true); @@ -287,7 +289,7 @@ namespace System.Threading.Tasks // If there's no processing currently happening but there are waiting exclusive tasks, // let's start processing those exclusive tasks. - Task processingTask = null; + Task? processingTask = null; if (m_processingCount == 0 && exclusiveTasksAreWaiting) { // Launch exclusive task processing @@ -296,17 +298,17 @@ namespace System.Threading.Tasks { try { - processingTask = new Task(thisPair => ((ConcurrentExclusiveSchedulerPair)thisPair).ProcessExclusiveTasks(), this, + processingTask = new Task(thisPair => ((ConcurrentExclusiveSchedulerPair)thisPair!).ProcessExclusiveTasks(), this, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 default, GetCreationOptionsForTask(fairly)); processingTask.Start(m_underlyingTaskScheduler); // When we call Start, if the underlying scheduler throws in QueueTask, TPL will fault the task and rethrow // the exception. To deal with that, we need a reference to the task object, so that we can observe its exception. // Hence, we separate creation and starting, so that we can store a reference to the task before we attempt QueueTask. } - catch + catch (Exception e) { m_processingCount = 0; - FaultWithTask(processingTask); + FaultWithTask(processingTask ?? Task.FromException(e)); } } } @@ -326,14 +328,14 @@ namespace System.Threading.Tasks { try { - processingTask = new Task(thisPair => ((ConcurrentExclusiveSchedulerPair)thisPair).ProcessConcurrentTasks(), this, + processingTask = new Task(thisPair => ((ConcurrentExclusiveSchedulerPair)thisPair!).ProcessConcurrentTasks(), this, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 default, GetCreationOptionsForTask(fairly)); processingTask.Start(m_underlyingTaskScheduler); // See above logic for why we use new + Start rather than StartNew } - catch + catch (Exception e) { --m_processingCount; - FaultWithTask(processingTask); + FaultWithTask(processingTask ?? Task.FromException(e)); } } } @@ -485,7 +487,7 @@ namespace System.Threading.Tasks /// <summary>Whether completion processing has been queued.</summary> internal bool m_completionQueued; /// <summary>Unrecoverable exceptions incurred while processing.</summary> - internal List<Exception> m_exceptions; + internal List<Exception>? m_exceptions; } /// <summary>Reusable immutable work item that can be scheduled to the thread pool to run processing.</summary> @@ -516,7 +518,7 @@ namespace System.Threading.Tasks private sealed class ConcurrentExclusiveTaskScheduler : TaskScheduler { /// <summary>Cached delegate for invoking TryExecuteTaskShim.</summary> - private static readonly Func<object, bool> s_tryExecuteTaskShim = new Func<object, bool>(TryExecuteTaskShim); + private static readonly Func<object?, bool> s_tryExecuteTaskShim = new Func<object?, bool>(TryExecuteTaskShim); /// <summary>The parent pair.</summary> private readonly ConcurrentExclusiveSchedulerPair m_pair; /// <summary>The maximum concurrency level for the scheduler.</summary> @@ -666,8 +668,9 @@ namespace System.Threading.Tasks /// This method is separated out not because of performance reasons but so that /// the SecuritySafeCritical attribute may be employed. /// </remarks> - private static bool TryExecuteTaskShim(object state) + private static bool TryExecuteTaskShim(object? state) { + Debug.Assert(state is Tuple<ConcurrentExclusiveTaskScheduler, Task>); var tuple = (Tuple<ConcurrentExclusiveTaskScheduler, Task>)state; return tuple.Item1.TryExecuteTask(tuple.Item2); } diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Future.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Future.cs index 0b93ee85df..9e562e3c46 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Future.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Future.cs @@ -10,6 +10,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -60,7 +61,7 @@ namespace System.Threading.Tasks [DebuggerDisplay("Id = {Id}, Status = {Status}, Method = {DebuggerDisplayMethodDescription}, Result = {DebuggerDisplayResultDescription}")] public class Task<TResult> : Task { - internal TResult m_result; // The value itself, if set. + internal TResult m_result = default!; // The value itself, if set. // TODO-NULLABLE-GENERIC private static readonly TaskFactory<TResult> s_Factory = new TaskFactory<TResult>(); @@ -75,14 +76,14 @@ namespace System.Threading.Tasks internal static readonly Func<Task<Task>, Task<TResult>> Value = completed => (Task<TResult>)completed.Result; } - // Construct a promise-style task without any options. + // Construct a promise-style task without any options. internal Task() : base() { } // Construct a promise-style task with state and options. - internal Task(object state, TaskCreationOptions options) : + internal Task(object? state, TaskCreationOptions options) : base(state, options, promiseStyle: true) { } @@ -209,7 +210,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ArgumentException"> /// The <paramref name="function"/> argument is null. /// </exception> - public Task(Func<object, TResult> function, object state) + public Task(Func<object?, TResult> function, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 : this(function, state, null, default, TaskCreationOptions.None, InternalTaskOptions.None, null) { @@ -230,7 +231,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see> /// has already been disposed. /// </exception> - public Task(Func<object, TResult> function, object state, CancellationToken cancellationToken) + public Task(Func<object?, TResult> function, object? state, CancellationToken cancellationToken) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 : this(function, state, null, cancellationToken, TaskCreationOptions.None, InternalTaskOptions.None, null) { @@ -255,7 +256,7 @@ namespace System.Threading.Tasks /// The <paramref name="creationOptions"/> argument specifies an invalid value for <see /// cref="T:System.Threading.Tasks.TaskCreationOptions"/>. /// </exception> - public Task(Func<object, TResult> function, object state, TaskCreationOptions creationOptions) + public Task(Func<object?, TResult> function, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 : this(function, state, Task.InternalCurrentIfAttached(creationOptions), default, creationOptions, InternalTaskOptions.None, null) { @@ -285,7 +286,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see> /// has already been disposed. /// </exception> - public Task(Func<object, TResult> function, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions) + public Task(Func<object?, TResult> function, object? state, CancellationToken cancellationToken, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 : this(function, state, Task.InternalCurrentIfAttached(creationOptions), cancellationToken, creationOptions, InternalTaskOptions.None, null) { @@ -300,8 +301,8 @@ namespace System.Threading.Tasks /// <param name="cancellationToken">The CancellationToken for the task.</param> /// <param name="creationOptions">Options to control the future's behavior.</param> /// <param name="internalOptions">Internal options to control the future's behavior.</param> - internal Task(Func<TResult> valueSelector, Task parent, CancellationToken cancellationToken, - TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) : + internal Task(Func<TResult> valueSelector, Task? parent, CancellationToken cancellationToken, + TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler? scheduler) : base(valueSelector, null, parent, cancellationToken, creationOptions, internalOptions, scheduler) { } @@ -316,15 +317,15 @@ namespace System.Threading.Tasks /// <param name="scheduler">The task scheduler which will be used to execute the future.</param> /// <param name="creationOptions">Options to control the future's behavior.</param> /// <param name="internalOptions">Internal options to control the future's behavior.</param> - internal Task(Delegate valueSelector, object state, Task parent, CancellationToken cancellationToken, - TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) : + internal Task(Delegate valueSelector, object? state, Task? parent, CancellationToken cancellationToken, + TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler? scheduler) : base(valueSelector, state, parent, cancellationToken, creationOptions, internalOptions, scheduler) { } // Internal method used by TaskFactory<TResult>.StartNew() methods - internal static Task<TResult> StartNew(Task parent, Func<TResult> function, CancellationToken cancellationToken, + internal static Task<TResult> StartNew(Task? parent, Func<TResult> function, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) { if (function == null) @@ -337,14 +338,14 @@ namespace System.Threading.Tasks } // Create and schedule the future. - Task<TResult> f = new Task<TResult>(function, parent, cancellationToken, creationOptions, internalOptions | InternalTaskOptions.QueuedByRuntime, scheduler); + Task<TResult> f = new Task<TResult>(function!, parent, cancellationToken, creationOptions, internalOptions | InternalTaskOptions.QueuedByRuntime, scheduler); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 f.ScheduleAndStart(false); return f; } // Internal method used by TaskFactory<TResult>.StartNew() methods - internal static Task<TResult> StartNew(Task parent, Func<object, TResult> function, object state, CancellationToken cancellationToken, + internal static Task<TResult> StartNew(Task? parent, Func<object?, TResult> function, object? state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) { if (function == null) @@ -357,7 +358,7 @@ namespace System.Threading.Tasks } // Create and schedule the future. - Task<TResult> f = new Task<TResult>(function, state, parent, cancellationToken, creationOptions, internalOptions | InternalTaskOptions.QueuedByRuntime, scheduler); + Task<TResult> f = new Task<TResult>(function!, state, parent, cancellationToken, creationOptions, internalOptions | InternalTaskOptions.QueuedByRuntime, scheduler); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 f.ScheduleAndStart(false); return f; @@ -377,8 +378,7 @@ namespace System.Threading.Tasks { get { - Delegate d = m_action; - return d != null ? d.Method.ToString() : "{null}"; + return m_action?.Method.ToString() ?? "{null}"; } } @@ -408,7 +408,7 @@ namespace System.Threading.Tasks // and which can be summarized more concisely with the following snippet from // FinishStageTwo, omitting everything that doesn't pertain to TrySetResult. Interlocked.Exchange(ref m_stateFlags, m_stateFlags | TASK_STATE_RAN_TO_COMPLETION); - ContingentProperties props = m_contingentProperties; + ContingentProperties? props = m_contingentProperties; if (props != null) { NotifyParentIfPotentiallyAttachedTask(); @@ -518,7 +518,7 @@ namespace System.Threading.Tasks return; } - if (m_action is Func<object, TResult> funcWithState) + if (m_action is Func<object?, TResult> funcWithState) { m_result = funcWithState(m_stateObject); return; @@ -726,13 +726,13 @@ namespace System.Threading.Tasks out internalOptions); Task continuationTask = new ContinuationTaskFromResultTask<TResult>( - this, continuationAction, null, + this, continuationAction!, null, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 creationOptions, internalOptions ); // Register the continuation. If synchronous execution is requested, this may // actually invoke the continuation before returning. - ContinueWithCore(continuationTask, scheduler, cancellationToken, continuationOptions); + ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 return continuationTask; } @@ -757,7 +757,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ArgumentNullException"> /// The <paramref name="continuationAction"/> argument is null. /// </exception> - public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state) + public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { return ContinueWith(continuationAction, state, TaskScheduler.Current, default, TaskContinuationOptions.None); } @@ -784,7 +784,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see> /// has already been disposed. /// </exception> - public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken) + public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, CancellationToken cancellationToken) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { return ContinueWith(continuationAction, state, TaskScheduler.Current, cancellationToken, TaskContinuationOptions.None); } @@ -813,7 +813,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ArgumentNullException"> /// The <paramref name="scheduler"/> argument is null. /// </exception> - public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, TaskScheduler scheduler) + public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, TaskScheduler scheduler) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { return ContinueWith(continuationAction, state, scheduler, default, TaskContinuationOptions.None); } @@ -847,7 +847,7 @@ namespace System.Threading.Tasks /// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see /// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>. /// </exception> - public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, TaskContinuationOptions continuationOptions) + public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, TaskContinuationOptions continuationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { return ContinueWith(continuationAction, state, TaskScheduler.Current, default, continuationOptions); } @@ -891,14 +891,14 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see> /// has already been disposed. /// </exception> - public Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, CancellationToken cancellationToken, + public Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, CancellationToken cancellationToken, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { return ContinueWith(continuationAction, state, scheduler, cancellationToken, continuationOptions); } // Same as the above overload, only with a stack mark. - internal Task ContinueWith(Action<Task<TResult>, object> continuationAction, object state, TaskScheduler scheduler, CancellationToken cancellationToken, + internal Task ContinueWith(Action<Task<TResult>, object?> continuationAction, object? state, TaskScheduler scheduler, CancellationToken cancellationToken, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 TaskContinuationOptions continuationOptions) { if (continuationAction == null) @@ -919,13 +919,13 @@ namespace System.Threading.Tasks out internalOptions); Task continuationTask = new ContinuationTaskFromResultTask<TResult>( - this, continuationAction, state, + this, continuationAction!, state, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 creationOptions, internalOptions ); // Register the continuation. If synchronous execution is requested, this may // actually invoke the continuation before returning. - ContinueWithCore(continuationTask, scheduler, cancellationToken, continuationOptions); + ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 return continuationTask; } @@ -1135,13 +1135,13 @@ namespace System.Threading.Tasks out internalOptions); Task<TNewResult> continuationFuture = new ContinuationResultTaskFromResultTask<TResult, TNewResult>( - this, continuationFunction, null, + this, continuationFunction!, null, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 creationOptions, internalOptions ); // Register the continuation. If synchronous execution is requested, this may // actually invoke the continuation before returning. - ContinueWithCore(continuationFuture, scheduler, cancellationToken, continuationOptions); + ContinueWithCore(continuationFuture, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 return continuationFuture; } @@ -1169,7 +1169,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ArgumentNullException"> /// The <paramref name="continuationFunction"/> argument is null. /// </exception> - public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state) + public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object?, TNewResult> continuationFunction, object? state) { return ContinueWith<TNewResult>(continuationFunction, state, TaskScheduler.Current, default, TaskContinuationOptions.None); } @@ -1199,7 +1199,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see> /// has already been disposed. /// </exception> - public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state, + public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object?, TNewResult> continuationFunction, object? state, CancellationToken cancellationToken) { return ContinueWith<TNewResult>(continuationFunction, state, TaskScheduler.Current, cancellationToken, TaskContinuationOptions.None); @@ -1231,7 +1231,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ArgumentNullException"> /// The <paramref name="scheduler"/> argument is null. /// </exception> - public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state, + public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object?, TNewResult> continuationFunction, object? state, TaskScheduler scheduler) { return ContinueWith<TNewResult>(continuationFunction, state, scheduler, default, TaskContinuationOptions.None); @@ -1275,7 +1275,7 @@ namespace System.Threading.Tasks /// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see /// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>. /// </exception> - public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state, + public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object?, TNewResult> continuationFunction, object? state, TaskContinuationOptions continuationOptions) { return ContinueWith<TNewResult>(continuationFunction, state, TaskScheduler.Current, default, continuationOptions); @@ -1330,14 +1330,14 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see> /// has already been disposed. /// </exception> - public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state, + public Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object?, TNewResult> continuationFunction, object? state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { return ContinueWith<TNewResult>(continuationFunction, state, scheduler, cancellationToken, continuationOptions); } // Same as the above overload, just with a stack mark. - internal Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object, TNewResult> continuationFunction, object state, + internal Task<TNewResult> ContinueWith<TNewResult>(Func<Task<TResult>, object?, TNewResult> continuationFunction, object? state, TaskScheduler scheduler, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions) { if (continuationFunction == null) @@ -1358,13 +1358,13 @@ namespace System.Threading.Tasks out internalOptions); Task<TNewResult> continuationFuture = new ContinuationResultTaskFromResultTask<TResult, TNewResult>( - this, continuationFunction, state, + this, continuationFunction!, state, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 creationOptions, internalOptions ); // Register the continuation. If synchronous execution is requested, this may // actually invoke the continuation before returning. - ContinueWithCore(continuationFuture, scheduler, cancellationToken, continuationOptions); + ContinueWithCore(continuationFuture, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 return continuationFuture; } @@ -1381,13 +1381,14 @@ namespace System.Threading.Tasks public SystemThreadingTasks_FutureDebugView(Task<TResult> task) { + Debug.Assert(task != null); m_task = task; } - public TResult Result { get { return m_task.Status == TaskStatus.RanToCompletion ? m_task.Result : default; } } - public object AsyncState { get { return m_task.AsyncState; } } + public TResult Result { get { return m_task.Status == TaskStatus.RanToCompletion ? m_task.Result : default!; } } // TODO-NULLABLE-GENERIC + public object? AsyncState { get { return m_task.AsyncState; } } public TaskCreationOptions CreationOptions { get { return m_task.CreationOptions; } } - public Exception Exception { get { return m_task.Exception; } } + public Exception? Exception { get { return m_task.Exception; } } public int Id { get { return m_task.Id; } } public bool CancellationPending { get { return (m_task.Status == TaskStatus.WaitingToRun) && m_task.CancellationToken.IsCancellationRequested; } } public TaskStatus Status { get { return m_task.Status; } } diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/FutureFactory.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/FutureFactory.cs index 55fab9a5de..c8145d87c6 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/FutureFactory.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/FutureFactory.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Threading.Tasks @@ -32,27 +33,20 @@ namespace System.Threading.Tasks // member variables private CancellationToken m_defaultCancellationToken; - private TaskScheduler m_defaultScheduler; + private TaskScheduler? m_defaultScheduler; private TaskCreationOptions m_defaultCreationOptions; private TaskContinuationOptions m_defaultContinuationOptions; - private TaskScheduler DefaultScheduler - { - get - { - if (m_defaultScheduler == null) return TaskScheduler.Current; - else return m_defaultScheduler; - } - } + private TaskScheduler DefaultScheduler => m_defaultScheduler ?? TaskScheduler.Current; // sister method to above property -- avoids a TLS lookup - private TaskScheduler GetDefaultScheduler(Task currTask) + private TaskScheduler GetDefaultScheduler(Task? currTask) { if (m_defaultScheduler != null) return m_defaultScheduler; else if ((currTask != null) && ((currTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0) ) - return currTask.ExecutingTaskScheduler; + return currTask.ExecutingTaskScheduler!; // a "current" task must be executing, which means it must have a scheduler else return TaskScheduler.Default; } @@ -116,7 +110,7 @@ namespace System.Threading.Tasks /// initialized to the current scheduler (see <see /// cref="System.Threading.Tasks.TaskScheduler.Current">TaskScheduler.Current</see>). /// </remarks> - public TaskFactory(TaskScheduler scheduler) // null means to use TaskScheduler.Current + public TaskFactory(TaskScheduler? scheduler) // null means to use TaskScheduler.Current : this(default, TaskCreationOptions.None, TaskContinuationOptions.None, scheduler) { } @@ -187,7 +181,7 @@ namespace System.Threading.Tasks /// current scheduler (see <see /// cref="System.Threading.Tasks.TaskScheduler.Current">TaskScheduler.Current</see>). /// </remarks> - public TaskFactory(CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) + public TaskFactory(CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions, TaskScheduler? scheduler) { TaskFactory.CheckMultiTaskContinuationOptions(continuationOptions); TaskFactory.CheckCreationOptions(creationOptions); @@ -221,7 +215,7 @@ namespace System.Threading.Tasks /// If null, <see cref="System.Threading.Tasks.TaskScheduler.Current">TaskScheduler.Current</see> /// will be used. /// </remarks> - public TaskScheduler Scheduler { get { return m_defaultScheduler; } } + public TaskScheduler? Scheduler { get { return m_defaultScheduler; } } /// <summary> /// Gets the <see cref="System.Threading.Tasks.TaskCreationOptions">TaskCreationOptions @@ -264,7 +258,7 @@ namespace System.Threading.Tasks /// </remarks> public Task<TResult> StartNew(Func<TResult> function) { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task<TResult>.StartNew(currTask, function, m_defaultCancellationToken, m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask)); } @@ -291,7 +285,7 @@ namespace System.Threading.Tasks /// </remarks> public Task<TResult> StartNew(Func<TResult> function, CancellationToken cancellationToken) { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task<TResult>.StartNew(currTask, function, cancellationToken, m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask)); } @@ -320,7 +314,7 @@ namespace System.Threading.Tasks /// </remarks> public Task<TResult> StartNew(Func<TResult> function, TaskCreationOptions creationOptions) { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task<TResult>.StartNew(currTask, function, m_defaultCancellationToken, creationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask)); } @@ -383,9 +377,9 @@ namespace System.Threading.Tasks /// However, unless creation and scheduling must be separated, StartNew is the recommended approach /// for both simplicity and performance. /// </remarks> - public Task<TResult> StartNew(Func<object, TResult> function, object state) + public Task<TResult> StartNew(Func<object?, TResult> function, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task<TResult>.StartNew(currTask, function, state, m_defaultCancellationToken, m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask)); } @@ -412,9 +406,9 @@ namespace System.Threading.Tasks /// However, unless creation and scheduling must be separated, StartNew is the recommended approach /// for both simplicity and performance. /// </remarks> - public Task<TResult> StartNew(Func<object, TResult> function, object state, CancellationToken cancellationToken) + public Task<TResult> StartNew(Func<object?, TResult> function, object? state, CancellationToken cancellationToken) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task<TResult>.StartNew(currTask, function, state, cancellationToken, m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask)); } @@ -443,9 +437,9 @@ namespace System.Threading.Tasks /// However, unless creation and scheduling must be separated, StartNew is the recommended approach /// for both simplicity and performance. /// </remarks> - public Task<TResult> StartNew(Func<object, TResult> function, object state, TaskCreationOptions creationOptions) + public Task<TResult> StartNew(Func<object?, TResult> function, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task<TResult>.StartNew(currTask, function, state, m_defaultCancellationToken, creationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask)); } @@ -485,7 +479,7 @@ namespace System.Threading.Tasks /// However, unless creation and scheduling must be separated, StartNew is the recommended approach /// for both simplicity and performance. /// </remarks> - public Task<TResult> StartNew(Func<object, TResult> function, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler) + public Task<TResult> StartNew(Func<object?, TResult> function, object? state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { return Task<TResult>.StartNew(Task.InternalCurrentIfAttached(creationOptions), function, state, cancellationToken, creationOptions, InternalTaskOptions.None, scheduler); @@ -498,16 +492,16 @@ namespace System.Threading.Tasks // Common core logic for FromAsync calls. This minimizes the chance of "drift" between overload implementations. private static void FromAsyncCoreLogic( IAsyncResult iar, - Func<IAsyncResult, TResult> endFunction, - Action<IAsyncResult> endAction, + Func<IAsyncResult, TResult>? endFunction, + Action<IAsyncResult>? endAction, Task<TResult> promise, bool requiresSynchronization) { Debug.Assert((endFunction != null) != (endAction != null), "Expected exactly one of endFunction/endAction to be non-null"); - Exception ex = null; - OperationCanceledException oce = null; - TResult result = default; + Exception? ex = null; + OperationCanceledException? oce = null; + TResult result = default!; // TODO-NULLABLE-GENERIC try { @@ -517,7 +511,7 @@ namespace System.Threading.Tasks } else { - endAction(iar); + endAction!(iar); } } catch (OperationCanceledException _oce) { oce = _oce; } @@ -636,8 +630,8 @@ namespace System.Threading.Tasks // method can access the logic w/o declaring a TaskFactory<TResult> instance. internal static Task<TResult> FromAsyncImpl( IAsyncResult asyncResult, - Func<IAsyncResult, TResult> endFunction, - Action<IAsyncResult> endAction, + Func<IAsyncResult, TResult>? endFunction, + Action<IAsyncResult>? endAction, TaskCreationOptions creationOptions, TaskScheduler scheduler) { @@ -654,7 +648,7 @@ namespace System.Threading.Tasks TaskFactory.CheckFromAsyncOptions(creationOptions, false); - Task<TResult> promise = new Task<TResult>((object)null, creationOptions); + Task<TResult> promise = new Task<TResult>((object?)null, creationOptions); if (AsyncCausalityTracer.LoggingOn) AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync"); @@ -669,7 +663,7 @@ namespace System.Threading.Tasks { FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: true); }), - (object)null, null, + (object?)null, null, default, TaskCreationOptions.None, InternalTaskOptions.None, null); if (AsyncCausalityTracer.LoggingOn) @@ -678,9 +672,9 @@ namespace System.Threading.Tasks if (Task.s_asyncDebuggingEnabled) Task.AddToActiveTasks(t); - if (asyncResult.IsCompleted) + if (asyncResult!.IsCompleted) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { - try { t.InternalRunSynchronously(scheduler, waitForCompletion: false); } + try { t.InternalRunSynchronously(scheduler!, waitForCompletion: false); } // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 catch (Exception e) { promise.TrySetException(e); } // catch and log any scheduler exceptions } else @@ -718,8 +712,8 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync( - Func<AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endMethod, object state) + Func<AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult> endMethod, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { return FromAsyncImpl(beginMethod, endMethod, null, state, m_defaultCreationOptions); } @@ -747,17 +741,17 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync( - Func<AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endMethod, object state, TaskCreationOptions creationOptions) + Func<AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult> endMethod, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { return FromAsyncImpl(beginMethod, endMethod, null, state, creationOptions); } // We need this logic broken out into a static method so that the similar TaskFactory.FromAsync() // method can access the logic w/o declaring a TaskFactory<TResult> instance. - internal static Task<TResult> FromAsyncImpl(Func<AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endFunction, Action<IAsyncResult> endAction, - object state, TaskCreationOptions creationOptions) + internal static Task<TResult> FromAsyncImpl(Func<AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult>? endFunction, Action<IAsyncResult>? endAction, + object? state, TaskCreationOptions creationOptions) { if (beginMethod == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.beginMethod); @@ -772,7 +766,7 @@ namespace System.Threading.Tasks Task<TResult> promise = new Task<TResult>(state, creationOptions); if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod.Method.Name); + AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod!.Method.Name); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 if (Task.s_asyncDebuggingEnabled) Task.AddToActiveTasks(promise); @@ -780,7 +774,7 @@ namespace System.Threading.Tasks try { //if we don't require synchronization, a faster set result path is taken - var asyncResult = beginMethod(iar => + var asyncResult = beginMethod!(iar => // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { if (!iar.CompletedSynchronously) FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); @@ -829,9 +823,9 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync<TArg1>( - Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, + Func<TArg1, AsyncCallback, object?, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod, - TArg1 arg1, object state) + TArg1 arg1, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { return FromAsyncImpl(beginMethod, endMethod, null, arg1, state, m_defaultCreationOptions); } @@ -863,18 +857,18 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync<TArg1>( - Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, + Func<TArg1, AsyncCallback, object?, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod, - TArg1 arg1, object state, TaskCreationOptions creationOptions) + TArg1 arg1, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { return FromAsyncImpl(beginMethod, endMethod, null, arg1, state, creationOptions); } // We need this logic broken out into a static method so that the similar TaskFactory.FromAsync() // method can access the logic w/o declaring a TaskFactory<TResult> instance. - internal static Task<TResult> FromAsyncImpl<TArg1>(Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endFunction, Action<IAsyncResult> endAction, - TArg1 arg1, object state, TaskCreationOptions creationOptions) + internal static Task<TResult> FromAsyncImpl<TArg1>(Func<TArg1, AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult>? endFunction, Action<IAsyncResult>? endAction, + TArg1 arg1, object? state, TaskCreationOptions creationOptions) { if (beginMethod == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.beginMethod); @@ -889,7 +883,7 @@ namespace System.Threading.Tasks Task<TResult> promise = new Task<TResult>(state, creationOptions); if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod.Method.Name); + AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod!.Method.Name); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 if (Task.s_asyncDebuggingEnabled) Task.AddToActiveTasks(promise); @@ -897,7 +891,7 @@ namespace System.Threading.Tasks try { //if we don't require synchronization, a faster set result path is taken - var asyncResult = beginMethod(arg1, iar => + var asyncResult = beginMethod!(arg1, iar => // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { if (!iar.CompletedSynchronously) FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); @@ -950,9 +944,9 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync<TArg1, TArg2>( - Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod, + Func<TArg1, TArg2, AsyncCallback, object?, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod, - TArg1 arg1, TArg2 arg2, object state) + TArg1 arg1, TArg2 arg2, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { return FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, state, m_defaultCreationOptions); } @@ -988,18 +982,18 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync<TArg1, TArg2>( - Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod, + Func<TArg1, TArg2, AsyncCallback, object?, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod, - TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions) + TArg1 arg1, TArg2 arg2, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { return FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, state, creationOptions); } // We need this logic broken out into a static method so that the similar TaskFactory.FromAsync() // method can access the logic w/o declaring a TaskFactory<TResult> instance. - internal static Task<TResult> FromAsyncImpl<TArg1, TArg2>(Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endFunction, Action<IAsyncResult> endAction, - TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions) + internal static Task<TResult> FromAsyncImpl<TArg1, TArg2>(Func<TArg1, TArg2, AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult>? endFunction, Action<IAsyncResult>? endAction, + TArg1 arg1, TArg2 arg2, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { if (beginMethod == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.beginMethod); @@ -1014,7 +1008,7 @@ namespace System.Threading.Tasks Task<TResult> promise = new Task<TResult>(state, creationOptions); if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod.Method.Name); + AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod!.Method.Name); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 if (Task.s_asyncDebuggingEnabled) Task.AddToActiveTasks(promise); @@ -1022,7 +1016,7 @@ namespace System.Threading.Tasks try { //if we don't require synchronization, a faster set result path is taken - var asyncResult = beginMethod(arg1, arg2, iar => + var asyncResult = beginMethod!(arg1, arg2, iar => // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { if (!iar.CompletedSynchronously) FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); @@ -1079,9 +1073,9 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync<TArg1, TArg2, TArg3>( - Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, + Func<TArg1, TArg2, TArg3, AsyncCallback, object?, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod, - TArg1 arg1, TArg2 arg2, TArg3 arg3, object state) + TArg1 arg1, TArg2 arg2, TArg3 arg3, object? state) { return FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, arg3, state, m_defaultCreationOptions); } @@ -1121,18 +1115,18 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync<TArg1, TArg2, TArg3>( - Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, + Func<TArg1, TArg2, TArg3, AsyncCallback, object?, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod, - TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions) + TArg1 arg1, TArg2 arg2, TArg3 arg3, object? state, TaskCreationOptions creationOptions) { return FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, arg3, state, creationOptions); } // We need this logic broken out into a static method so that the similar TaskFactory.FromAsync() // method can access the logic w/o declaring a TaskFactory<TResult> instance. - internal static Task<TResult> FromAsyncImpl<TArg1, TArg2, TArg3>(Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endFunction, Action<IAsyncResult> endAction, - TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions) + internal static Task<TResult> FromAsyncImpl<TArg1, TArg2, TArg3>(Func<TArg1, TArg2, TArg3, AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult>? endFunction, Action<IAsyncResult>? endAction, + TArg1 arg1, TArg2 arg2, TArg3 arg3, object? state, TaskCreationOptions creationOptions) { if (beginMethod == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.beginMethod); @@ -1147,7 +1141,7 @@ namespace System.Threading.Tasks Task<TResult> promise = new Task<TResult>(state, creationOptions); if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod.Method.Name); + AsyncCausalityTracer.TraceOperationCreation(promise, "TaskFactory.FromAsync: " + beginMethod!.Method.Name); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 if (Task.s_asyncDebuggingEnabled) Task.AddToActiveTasks(promise); @@ -1155,7 +1149,7 @@ namespace System.Threading.Tasks try { //if we don't require synchronization, a faster set result path is taken - var asyncResult = beginMethod(arg1, arg2, arg3, iar => + var asyncResult = beginMethod!(arg1, arg2, arg3, iar => // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { if (!iar.CompletedSynchronously) FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true); @@ -1237,7 +1231,7 @@ namespace System.Threading.Tasks /// <summary>A reference to the object on which the begin/end methods are invoked.</summary> private TInstance m_thisRef; /// <summary>The end method.</summary> - private Func<TInstance, IAsyncResult, TResult> m_endMethod; + private Func<TInstance, IAsyncResult, TResult>? m_endMethod; /// <summary>Initializes the promise.</summary> /// <param name="thisRef">A reference to the object on which the begin/end methods are invoked.</param> @@ -1260,13 +1254,13 @@ namespace System.Threading.Tasks // Validate argument if (asyncResult == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.asyncResult); - var promise = asyncResult.AsyncState as FromAsyncTrimPromise<TInstance>; + var promise = asyncResult!.AsyncState as FromAsyncTrimPromise<TInstance>; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 if (promise == null) ThrowHelper.ThrowArgumentException(ExceptionResource.InvalidOperation_WrongAsyncResultOrEndCalledMultiple, ExceptionArgument.asyncResult); // Grab the relevant state and then null it out so that the task doesn't hold onto the state unnecessarily - var thisRef = promise.m_thisRef; + var thisRef = promise!.m_thisRef; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 var endMethod = promise.m_endMethod; - promise.m_thisRef = default; + promise.m_thisRef = default!; // TODO-NULLABLE-GENERIC promise.m_endMethod = null; if (endMethod == null) ThrowHelper.ThrowArgumentException(ExceptionResource.InvalidOperation_WrongAsyncResultOrEndCalledMultiple, ExceptionArgument.asyncResult); @@ -1274,7 +1268,7 @@ namespace System.Threading.Tasks // we'll instead complete the promise at the call site. if (!asyncResult.CompletedSynchronously) { - promise.Complete(thisRef, endMethod, asyncResult, requiresSynchronization: true); + promise.Complete(thisRef, endMethod!, asyncResult, requiresSynchronization: true); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } } @@ -1328,9 +1322,8 @@ namespace System.Threading.Tasks private static Task<TResult> CreateCanceledTask(TaskContinuationOptions continuationOptions, CancellationToken ct) { TaskCreationOptions tco; - InternalTaskOptions dontcare; - Task.CreationOptionsFromContinuationOptions(continuationOptions, out tco, out dontcare); - return new Task<TResult>(true, default, tco, ct); + Task.CreationOptionsFromContinuationOptions(continuationOptions, out tco, out _); + return new Task<TResult>(true, default!, tco, ct); // TODO-NULLABLE-GENERIC } // @@ -1607,7 +1600,7 @@ namespace System.Threading.Tasks // Core implementation of ContinueWhenAll -- the generic version // Note: if you make any changes to this method, please do the same to the non-generic version too. internal static Task<TResult> ContinueWhenAllImpl<TAntecedentResult>(Task<TAntecedentResult>[] tasks, - Func<Task<TAntecedentResult>[], TResult> continuationFunction, Action<Task<TAntecedentResult>[]> continuationAction, + Func<Task<TAntecedentResult>[], TResult>? continuationFunction, Action<Task<TAntecedentResult>[]>? continuationAction, TaskContinuationOptions continuationOptions, CancellationToken cancellationToken, TaskScheduler scheduler) { // check arguments @@ -1618,7 +1611,7 @@ namespace System.Threading.Tasks if (scheduler == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler); // Check tasks array and make defensive copy - Task<TAntecedentResult>[] tasksCopy = TaskFactory.CheckMultiContinuationTasksAndCopy<TAntecedentResult>(tasks); + Task<TAntecedentResult>[] tasksCopy = TaskFactory.CheckMultiContinuationTasksAndCopy<TAntecedentResult>(tasks!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 // Bail early if cancellation has been requested. if (cancellationToken.IsCancellationRequested @@ -1637,7 +1630,7 @@ namespace System.Threading.Tasks return starter.ContinueWith<TResult>( // use a cached delegate GenericDelegateCache<TAntecedentResult, TResult>.CWAllFuncDelegate, - continuationFunction, scheduler, cancellationToken, continuationOptions); + continuationFunction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } else { @@ -1646,14 +1639,14 @@ namespace System.Threading.Tasks return starter.ContinueWith<TResult>( // use a cached delegate GenericDelegateCache<TAntecedentResult, TResult>.CWAllActionDelegate, - continuationAction, scheduler, cancellationToken, continuationOptions); + continuationAction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } } // Core implementation of ContinueWhenAll -- the non-generic version // Note: if you make any changes to this method, please do the same to the generic version too. internal static Task<TResult> ContinueWhenAllImpl(Task[] tasks, - Func<Task[], TResult> continuationFunction, Action<Task[]> continuationAction, + Func<Task[], TResult>? continuationFunction, Action<Task[]>? continuationAction, TaskContinuationOptions continuationOptions, CancellationToken cancellationToken, TaskScheduler scheduler) { // check arguments @@ -1664,7 +1657,7 @@ namespace System.Threading.Tasks if (scheduler == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler); // Check tasks array and make defensive copy - Task[] tasksCopy = TaskFactory.CheckMultiContinuationTasksAndCopy(tasks); + Task[] tasksCopy = TaskFactory.CheckMultiContinuationTasksAndCopy(tasks!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 // Bail early if cancellation has been requested. if (cancellationToken.IsCancellationRequested @@ -1687,9 +1680,10 @@ namespace System.Threading.Tasks (completedTasks, state) => { completedTasks.NotifyDebuggerOfWaitCompletionIfNecessary(); + Debug.Assert(state is Func<Task[], TResult>); return ((Func<Task[], TResult>)state)(completedTasks.Result); }, - continuationFunction, scheduler, cancellationToken, continuationOptions); + continuationFunction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } else { @@ -1701,9 +1695,10 @@ namespace System.Threading.Tasks (completedTasks, state) => { completedTasks.NotifyDebuggerOfWaitCompletionIfNecessary(); - ((Action<Task[]>)state)(completedTasks.Result); return default; + Debug.Assert(state is Action<Task[]>); + ((Action<Task[]>)state)(completedTasks.Result); return default!; // TODO-NULLABLE-GENERIC }, - continuationAction, scheduler, cancellationToken, continuationOptions); + continuationAction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } } @@ -1980,13 +1975,13 @@ namespace System.Threading.Tasks // Core implementation of ContinueWhenAny, non-generic version // Note: if you make any changes to this method, be sure to do the same to the generic version internal static Task<TResult> ContinueWhenAnyImpl(Task[] tasks, - Func<Task, TResult> continuationFunction, Action<Task> continuationAction, + Func<Task, TResult>? continuationFunction, Action<Task>? continuationAction, TaskContinuationOptions continuationOptions, CancellationToken cancellationToken, TaskScheduler scheduler) { // check arguments TaskFactory.CheckMultiTaskContinuationOptions(continuationOptions); if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks); - if (tasks.Length == 0) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_EmptyTaskList, ExceptionArgument.tasks); + if (tasks!.Length == 0) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_EmptyTaskList, ExceptionArgument.tasks); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 //ArgumentNullException of continuationFunction or continuationAction is checked by the caller Debug.Assert((continuationFunction != null) != (continuationAction != null), "Expected exactly one of endFunction/endAction to be non-null"); @@ -2009,8 +2004,12 @@ namespace System.Threading.Tasks return starter.ContinueWith( //the following delegate avoids closure capture as much as possible //completedTask.Result is the winning task; state == continuationAction - (completedTask, state) => { return ((Func<Task, TResult>)state)(completedTask.Result); }, - continuationFunction, scheduler, cancellationToken, continuationOptions); + (completedTask, state) => + { + Debug.Assert(state is Func<Task, TResult>); + return ((Func<Task, TResult>)state)(completedTask.Result); + }, + continuationFunction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } else { @@ -2018,8 +2017,13 @@ namespace System.Threading.Tasks return starter.ContinueWith<TResult>( //the following delegate avoids closure capture as much as possible //completedTask.Result is the winning task; state == continuationAction - (completedTask, state) => { ((Action<Task>)state)(completedTask.Result); return default; }, - continuationAction, scheduler, cancellationToken, continuationOptions); + (completedTask, state) => + { + Debug.Assert(state is Action<Task>); + ((Action<Task>)state)(completedTask.Result); + return default!; // TODO-NULLABLE-GENERIC + }, + continuationAction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } } @@ -2027,13 +2031,13 @@ namespace System.Threading.Tasks // Core implementation of ContinueWhenAny, generic version // Note: if you make any changes to this method, be sure to do the same to the non-generic version internal static Task<TResult> ContinueWhenAnyImpl<TAntecedentResult>(Task<TAntecedentResult>[] tasks, - Func<Task<TAntecedentResult>, TResult> continuationFunction, Action<Task<TAntecedentResult>> continuationAction, + Func<Task<TAntecedentResult>, TResult>? continuationFunction, Action<Task<TAntecedentResult>>? continuationAction, TaskContinuationOptions continuationOptions, CancellationToken cancellationToken, TaskScheduler scheduler) { // check arguments TaskFactory.CheckMultiTaskContinuationOptions(continuationOptions); if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks); - if (tasks.Length == 0) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_EmptyTaskList, ExceptionArgument.tasks); + if (tasks!.Length == 0) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_EmptyTaskList, ExceptionArgument.tasks); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 //ArgumentNullException of continuationFunction or continuationAction is checked by the caller Debug.Assert((continuationFunction != null) != (continuationAction != null), "Expected exactly one of endFunction/endAction to be non-null"); if (scheduler == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler); @@ -2055,7 +2059,7 @@ namespace System.Threading.Tasks return starter.ContinueWith<TResult>( // Use a cached delegate GenericDelegateCache<TAntecedentResult, TResult>.CWAnyFuncDelegate, - continuationFunction, scheduler, cancellationToken, continuationOptions); + continuationFunction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } else { @@ -2063,7 +2067,7 @@ namespace System.Threading.Tasks return starter.ContinueWith<TResult>( // Use a cached delegate GenericDelegateCache<TAntecedentResult, TResult>.CWAnyActionDelegate, - continuationAction, scheduler, cancellationToken, continuationOptions); + continuationAction, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } } } @@ -2074,41 +2078,45 @@ namespace System.Threading.Tasks internal static class GenericDelegateCache<TAntecedentResult, TResult> { // ContinueWith delegate for TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(non-null continuationFunction) - internal static Func<Task<Task>, object, TResult> CWAnyFuncDelegate = - (Task<Task> wrappedWinner, object state) => + internal static Func<Task<Task>, object?, TResult> CWAnyFuncDelegate = + (Task<Task> wrappedWinner, object? state) => { + Debug.Assert(state is Func<Task<TAntecedentResult>, TResult>); var func = (Func<Task<TAntecedentResult>, TResult>)state; var arg = (Task<TAntecedentResult>)wrappedWinner.Result; return func(arg); }; // ContinueWith delegate for TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(non-null continuationAction) - internal static Func<Task<Task>, object, TResult> CWAnyActionDelegate = - (Task<Task> wrappedWinner, object state) => + internal static Func<Task<Task>, object?, TResult> CWAnyActionDelegate = + (Task<Task> wrappedWinner, object? state) => { + Debug.Assert(state is Action<Task<TAntecedentResult>>); var action = (Action<Task<TAntecedentResult>>)state; var arg = (Task<TAntecedentResult>)wrappedWinner.Result; action(arg); - return default; + return default!; // TODO-NULLABLE-GENERIC }; // ContinueWith delegate for TaskFactory<TResult>.ContinueWhenAllImpl<TAntecedentResult>(non-null continuationFunction) - internal static Func<Task<Task<TAntecedentResult>[]>, object, TResult> CWAllFuncDelegate = - (Task<Task<TAntecedentResult>[]> wrappedAntecedents, object state) => + internal static Func<Task<Task<TAntecedentResult>[]>, object?, TResult> CWAllFuncDelegate = + (Task<Task<TAntecedentResult>[]> wrappedAntecedents, object? state) => { wrappedAntecedents.NotifyDebuggerOfWaitCompletionIfNecessary(); + Debug.Assert(state is Func<Task<TAntecedentResult>[], TResult>); var func = (Func<Task<TAntecedentResult>[], TResult>)state; return func(wrappedAntecedents.Result); }; // ContinueWith delegate for TaskFactory<TResult>.ContinueWhenAllImpl<TAntecedentResult>(non-null continuationAction) - internal static Func<Task<Task<TAntecedentResult>[]>, object, TResult> CWAllActionDelegate = - (Task<Task<TAntecedentResult>[]> wrappedAntecedents, object state) => + internal static Func<Task<Task<TAntecedentResult>[]>, object?, TResult> CWAllActionDelegate = + (Task<Task<TAntecedentResult>[]> wrappedAntecedents, object? state) => { wrappedAntecedents.NotifyDebuggerOfWaitCompletionIfNecessary(); + Debug.Assert(state is Action<Task<TAntecedentResult>[]>); var action = (Action<Task<TAntecedentResult>[]>)state; action(wrappedAntecedents.Result); - return default; + return default!; // TODO-NULLABLE-GENERIC }; } } diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ProducerConsumerQueues.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ProducerConsumerQueues.cs index 1880288c51..21214e85a8 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ProducerConsumerQueues.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ProducerConsumerQueues.cs @@ -21,6 +21,7 @@ // ************</IMPORTANT NOTE>************* // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; @@ -204,7 +205,7 @@ namespace System.Threading.Tasks if (first != segment.m_state.m_lastCopy) { result = array[first]; - array[first] = default; // Clear the slot to release the element + array[first] = default!; // Clear the slot to release the element // TODO-NULLABLE-GENERIC segment.m_state.m_first = (first + 1) & (array.Length - 1); return true; } @@ -239,12 +240,12 @@ namespace System.Threading.Tasks if (first == segment.m_state.m_last) { - result = default; + result = default!; // TODO-NULLABLE-GENERIC return false; } result = array[first]; - array[first] = default; // Clear the slot to release the element + array[first] = default!; // Clear the slot to release the element // TODO-NULLABLE-GENERIC segment.m_state.m_first = (first + 1) & (segment.m_array.Length - 1); segment.m_state.m_lastCopy = segment.m_state.m_last; // Refresh m_lastCopy to ensure that m_first has not passed m_lastCopy @@ -269,7 +270,7 @@ namespace System.Threading.Tasks /// <remarks>WARNING: This should only be used for debugging purposes. It is not safe to be used concurrently.</remarks> public IEnumerator<T> GetEnumerator() { - for (Segment segment = m_head; segment != null; segment = segment.m_next) + for (Segment? segment = m_head; segment != null; segment = segment.m_next) { for (int pt = segment.m_state.m_first; pt != segment.m_state.m_last; @@ -290,7 +291,7 @@ namespace System.Threading.Tasks get { int count = 0; - for (Segment segment = m_head; segment != null; segment = segment.m_next) + for (Segment? segment = m_head; segment != null; segment = segment.m_next) { int arraySize = segment.m_array.Length; int first, last; @@ -311,7 +312,7 @@ namespace System.Threading.Tasks private sealed class Segment { /// <summary>The next segment in the linked list of segments.</summary> - internal Segment m_next; + internal Segment? m_next; /// <summary>The data stored in this segment.</summary> internal readonly T[] m_array; /// <summary>Details about the segment.</summary> diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/IValueTaskSource.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/IValueTaskSource.cs index e411146a1d..6181ab2bf0 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/IValueTaskSource.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/IValueTaskSource.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading.Tasks.Sources { /// <summary> @@ -53,7 +54,7 @@ namespace System.Threading.Tasks.Sources /// <param name="state">The state object to pass to <paramref name="continuation"/> when it's invoked.</param> /// <param name="token">Opaque value that was provided to the <see cref="ValueTask"/>'s constructor.</param> /// <param name="flags">The flags describing the behavior of the continuation.</param> - void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags); + void OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 /// <summary>Gets the result of the <see cref="IValueTaskSource"/>.</summary> /// <param name="token">Opaque value that was provided to the <see cref="ValueTask"/>'s constructor.</param> @@ -73,7 +74,7 @@ namespace System.Threading.Tasks.Sources /// <param name="state">The state object to pass to <paramref name="continuation"/> when it's invoked.</param> /// <param name="token">Opaque value that was provided to the <see cref="ValueTask"/>'s constructor.</param> /// <param name="flags">The flags describing the behavior of the continuation.</param> - void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags); + void OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 /// <summary>Gets the result of the <see cref="IValueTaskSource{TResult}"/>.</summary> /// <param name="token">Opaque value that was provided to the <see cref="ValueTask"/>'s constructor.</param> diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs index 797ed6ed8a..967cbbeadf 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; @@ -18,22 +19,22 @@ namespace System.Threading.Tasks.Sources /// or <see cref="ManualResetValueTaskSourceCoreShared.s_sentinel"/> if the operation completed before a callback was supplied, /// or null if a callback hasn't yet been provided and the operation hasn't yet completed. /// </summary> - private Action<object> _continuation; + private Action<object?>? _continuation; /// <summary>State to pass to <see cref="_continuation"/>.</summary> - private object _continuationState; + private object? _continuationState; /// <summary><see cref="ExecutionContext"/> to flow to the callback, or null if no flowing is required.</summary> - private ExecutionContext _executionContext; + private ExecutionContext? _executionContext; /// <summary> /// A "captured" <see cref="SynchronizationContext"/> or <see cref="TaskScheduler"/> with which to invoke the callback, /// or null if no special context is required. /// </summary> - private object _capturedContext; + private object? _capturedContext; /// <summary>Whether the current operation has completed.</summary> private bool _completed; /// <summary>The result with which the operation succeeded, or the default value if it hasn't yet completed or failed.</summary> private TResult _result; /// <summary>The exception with which the operation failed, or null if it hasn't yet completed or completed successfully.</summary> - private ExceptionDispatchInfo _error; + private ExceptionDispatchInfo? _error; /// <summary>The current version of this value, used to help prevent misuse.</summary> private short _version; @@ -47,7 +48,7 @@ namespace System.Threading.Tasks.Sources // Reset/update state for the next use/await of this instance. _version++; _completed = false; - _result = default; + _result = default!; // TODO-NULLABLE-GENERIC _error = null; _executionContext = null; _capturedContext = null; @@ -106,7 +107,7 @@ namespace System.Threading.Tasks.Sources /// <param name="state">The state object to pass to <paramref name="continuation"/> when it's invoked.</param> /// <param name="token">Opaque value that was provided to the <see cref="ValueTask"/>'s constructor.</param> /// <param name="flags">The flags describing the behavior of the continuation.</param> - public void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) + public void OnCompleted(Action<object?> continuation, object? state, short token, ValueTaskSourceOnCompletedFlags flags) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { if (continuation == null) { @@ -121,7 +122,7 @@ namespace System.Threading.Tasks.Sources if ((flags & ValueTaskSourceOnCompletedFlags.UseSchedulingContext) != 0) { - SynchronizationContext sc = SynchronizationContext.Current; + SynchronizationContext? sc = SynchronizationContext.Current; if (sc != null && sc.GetType() != typeof(SynchronizationContext)) { _capturedContext = sc; @@ -144,7 +145,7 @@ namespace System.Threading.Tasks.Sources // To minimize the chances of that, we check preemptively whether _continuation // is already set to something other than the completion sentinel. - object oldContinuation = _continuation; + object? oldContinuation = _continuation; if (oldContinuation == null) { _continuationState = state; @@ -175,7 +176,7 @@ namespace System.Threading.Tasks.Sources case SynchronizationContext sc: sc.Post(s => { - var tuple = (Tuple<Action<object>, object>)s; + var tuple = (Tuple<Action<object?>, object?>)s!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 tuple.Item1(tuple.Item2); }, Tuple.Create(continuation, state)); break; @@ -229,6 +230,8 @@ namespace System.Threading.Tasks.Sources /// </summary> private void InvokeContinuation() { + Debug.Assert(_continuation != null); + switch (_capturedContext) { case null: @@ -252,7 +255,7 @@ namespace System.Threading.Tasks.Sources case SynchronizationContext sc: sc.Post(s => { - var state = (Tuple<Action<object>, object>)s; + var state = (Tuple<Action<object?>, object?>)s!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 state.Item1(state.Item2); }, Tuple.Create(_continuation, _continuationState)); break; @@ -266,8 +269,8 @@ namespace System.Threading.Tasks.Sources internal static class ManualResetValueTaskSourceCoreShared // separated out of generic to avoid unnecessary duplication { - internal static readonly Action<object> s_sentinel = CompletionSentinel; - private static void CompletionSentinel(object _) // named method to aid debugging + internal static readonly Action<object?> s_sentinel = CompletionSentinel; + private static void CompletionSentinel(object? _) // named method to aid debugging { Debug.Fail("The sentinel delegate should never be invoked."); ThrowHelper.ThrowInvalidOperationException(); diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs index 5d893c5cee..a8aac04936 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs @@ -10,6 +10,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; @@ -130,13 +131,13 @@ namespace System.Threading.Tasks public class Task : IAsyncResult, IDisposable { [ThreadStatic] - internal static Task t_currentTask; // The currently executing task. + internal static Task? t_currentTask; // The currently executing task. internal static int s_taskIdCounter; //static counter used to generate unique task IDs private volatile int m_taskId; // this task's unique ID. initialized only if it is ever requested - internal Delegate m_action; // The body of the task. Might be Action<object>, Action<TState> or Action. Or possibly a Func. + internal Delegate? m_action; // The body of the task. Might be Action<object>, Action<TState> or Action. Or possibly a Func. // If m_action is set to null it will indicate that we operate in the // "externally triggered completion" mode, which is exclusively meant // for the signalling Task<TResult> (aka. promise). In this mode, @@ -145,12 +146,12 @@ namespace System.Threading.Tasks // But the event would now be signalled if Cancel() is called - internal object m_stateObject; // A state object that can be optionally supplied, passed to action. - internal TaskScheduler m_taskScheduler; // The task scheduler this task runs under. + internal object? m_stateObject; // A state object that can be optionally supplied, passed to action. + internal TaskScheduler? m_taskScheduler; // The task scheduler this task runs under. internal volatile int m_stateFlags; // SOS DumpAsync command depends on this name - private Task ParentForDebugger => m_contingentProperties?.m_parent; // Private property used by a debugger to access this Task's parent + private Task? ParentForDebugger => m_contingentProperties?.m_parent; // Private property used by a debugger to access this Task's parent private int StateFlagsForDebugger => m_stateFlags; // Private property used by a debugger to access this Task's state flags // State constants for m_stateFlags; @@ -188,7 +189,7 @@ namespace System.Threading.Tasks // Can be null, a single continuation, a list of continuations, or s_taskCompletionSentinel, // in that order. The logic arround this object assumes it will never regress to a previous state. - private volatile object m_continuationObject = null; // SOS DumpAsync command depends on this name + private volatile object? m_continuationObject = null; // SOS DumpAsync command depends on this name // m_continuationObject is set to this when the task completes. private static readonly object s_taskCompletionSentinel = new object(); @@ -199,7 +200,7 @@ namespace System.Threading.Tasks // This dictonary relates the task id, from an operation id located in the Async Causality log to the actual // task. This is to be used by the debugger ONLY. Task in this dictionary represent current active tasks. - private static Dictionary<int, Task> s_currentActiveTasks; + private static Dictionary<int, Task>? s_currentActiveTasks; // These methods are a way to access the dictionary both from this class and for other classes that also // activate dummy tasks. Specifically the AsyncTaskMethodBuilder and AsyncTaskMethodBuilder<> @@ -210,9 +211,9 @@ namespace System.Threading.Tasks LazyInitializer.EnsureInitialized(ref s_currentActiveTasks, () => new Dictionary<int, Task>()); int taskId = task.Id; - lock (s_currentActiveTasks) + lock (s_currentActiveTasks!) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { - s_currentActiveTasks[taskId] = task; + s_currentActiveTasks![taskId] = task; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } //always return true to keep signature as bool for backwards compatibility return true; @@ -238,17 +239,17 @@ namespace System.Threading.Tasks { // Additional context - internal ExecutionContext m_capturedContext; // The execution context to run the task within, if any. Only set from non-concurrent contexts. + internal ExecutionContext? m_capturedContext; // The execution context to run the task within, if any. Only set from non-concurrent contexts. // Completion fields (exceptions and event) - internal volatile ManualResetEventSlim m_completionEvent; // Lazily created if waiting is required. - internal volatile TaskExceptionHolder m_exceptionsHolder; // Tracks exceptions, if any have occurred + internal volatile ManualResetEventSlim? m_completionEvent; // Lazily created if waiting is required. + internal volatile TaskExceptionHolder? m_exceptionsHolder; // Tracks exceptions, if any have occurred // Cancellation fields (token, registration, and internally requested) internal CancellationToken m_cancellationToken; // Task's cancellation token, if it has one - internal Shared<CancellationTokenRegistration> m_cancellationRegistration; // Task's registration with the cancellation token + internal Shared<CancellationTokenRegistration>? m_cancellationRegistration; // Task's registration with the cancellation token internal volatile int m_internalCancellationRequested; // Its own field because multiple threads legally try to set it. // Parenting fields @@ -260,9 +261,9 @@ namespace System.Threading.Tasks internal volatile int m_completionCountdown = 1; // A list of child tasks that threw an exception (TCEs don't count), // but haven't yet been waited on by the parent, lazily initialized. - internal volatile List<Task> m_exceptionalChildren; + internal volatile List<Task>? m_exceptionalChildren; // A task's parent, or null if parent-less. Only set during Task construction. - internal Task m_parent; + internal Task? m_parent; /// <summary> /// Sets the internal completion event. @@ -295,7 +296,7 @@ namespace System.Threading.Tasks // This field will only be instantiated to some non-null value if any ContingentProperties need to be set. // This will be a ContingentProperties instance or a type derived from it - internal ContingentProperties m_contingentProperties; + internal ContingentProperties? m_contingentProperties; // Special internal constructor to create an already-completed task. // if canceled==true, create a Canceled task, or else create a RanToCompletion task. @@ -325,7 +326,7 @@ namespace System.Threading.Tasks // Special constructor for use with promise-style tasks. // Added promiseStyle parameter as an aid to the compiler to distinguish between (state,TCO) and // (action,TCO). It should always be true. - internal Task(object state, TaskCreationOptions creationOptions, bool promiseStyle) + internal Task(object? state, TaskCreationOptions creationOptions, bool promiseStyle) { Debug.Assert(promiseStyle, "Promise CTOR: promiseStyle was false"); @@ -339,7 +340,7 @@ namespace System.Threading.Tasks // Only set a parent if AttachedToParent is specified. if ((creationOptions & TaskCreationOptions.AttachedToParent) != 0) { - Task parent = Task.InternalCurrent; + Task? parent = Task.InternalCurrent; if (parent != null) { EnsureContingentPropertiesInitializedUnsafe().m_parent = parent; @@ -427,7 +428,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ArgumentNullException"> /// The <paramref name="action"/> argument is null. /// </exception> - public Task(Action<object> action, object state) + public Task(Action<object?> action, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 : this(action, state, null, default, TaskCreationOptions.None, InternalTaskOptions.None, null) { } @@ -444,7 +445,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see> /// has already been disposed. /// </exception> - public Task(Action<object> action, object state, CancellationToken cancellationToken) + public Task(Action<object?> action, object? state, CancellationToken cancellationToken) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 : this(action, state, null, cancellationToken, TaskCreationOptions.None, InternalTaskOptions.None, null) { } @@ -465,7 +466,7 @@ namespace System.Threading.Tasks /// The <paramref name="creationOptions"/> argument specifies an invalid value for <see /// cref="T:System.Threading.Tasks.TaskCreationOptions"/>. /// </exception> - public Task(Action<object> action, object state, TaskCreationOptions creationOptions) + public Task(Action<object?> action, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 : this(action, state, Task.InternalCurrentIfAttached(creationOptions), default, creationOptions, InternalTaskOptions.None, null) { } @@ -490,7 +491,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see> /// has already been disposed. /// </exception> - public Task(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions) + public Task(Action<object?> action, object? state, CancellationToken cancellationToken, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 : this(action, state, Task.InternalCurrentIfAttached(creationOptions), cancellationToken, creationOptions, InternalTaskOptions.None, null) { } @@ -505,8 +506,8 @@ namespace System.Threading.Tasks /// <param name="scheduler">A task scheduler under which the task will run.</param> /// <param name="creationOptions">Options to control its execution.</param> /// <param name="internalOptions">Internal options to control its execution</param> - internal Task(Delegate action, object state, Task parent, CancellationToken cancellationToken, - TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) + internal Task(Delegate action, object? state, Task? parent, CancellationToken cancellationToken, + TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler? scheduler) { if (action == null) { @@ -537,8 +538,8 @@ namespace System.Threading.Tasks /// <param name="cancellationToken">A CancellationToken for the Task.</param> /// <param name="creationOptions">Options to customize behavior of Task.</param> /// <param name="internalOptions">Internal options to customize behavior of Task.</param> - internal void TaskConstructorCore(Delegate action, object state, CancellationToken cancellationToken, - TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) + internal void TaskConstructorCore(Delegate? action, object? state, CancellationToken cancellationToken, + TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler? scheduler) { m_action = action; m_stateObject = state; @@ -580,10 +581,10 @@ namespace System.Threading.Tasks // We can safely call the creator task's AddNewChild() method to register it, // because at this point we are already on its thread of execution. - ContingentProperties props = m_contingentProperties; + ContingentProperties? props = m_contingentProperties; if (props != null) { - Task parent = props.m_parent; + Task? parent = props.m_parent; if (parent != null && ((creationOptions & TaskCreationOptions.AttachedToParent) != 0) && ((parent.CreationOptions & TaskCreationOptions.DenyChildAttach) == 0)) @@ -606,7 +607,7 @@ namespace System.Threading.Tasks /// Handles everything needed for associating a CancellationToken with a task which is being constructed. /// This method is meant to be called either from the TaskConstructorCore or from ContinueWithCore. /// </summary> - private void AssignCancellationToken(CancellationToken cancellationToken, Task antecedent, TaskContinuation continuation) + private void AssignCancellationToken(CancellationToken cancellationToken, Task? antecedent, TaskContinuation? continuation) { // There is no need to worry about concurrency issues here because we are in the constructor path of the task -- // there should not be any race conditions to set m_contingentProperties at this point. @@ -634,16 +635,18 @@ namespace System.Threading.Tasks if (antecedent == null) { // if no antecedent was specified, use this task's reference as the cancellation state object - ctr = cancellationToken.UnsafeRegister(t => ((Task)t).InternalCancel(false), this); + ctr = cancellationToken.UnsafeRegister(t => ((Task)t!).InternalCancel(false), this); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } else { + Debug.Assert(continuation != null); + // If an antecedent was specified, pack this task, its antecedent and the TaskContinuation together as a tuple // and use it as the cancellation state object. This will be unpacked in the cancellation callback so that // antecedent.RemoveCancellation(continuation) can be invoked. ctr = cancellationToken.UnsafeRegister(t => { - var tuple = (Tuple<Task, Task, TaskContinuation>)t; + var tuple = (Tuple<Task, Task, TaskContinuation>)t!; Task targetTask = tuple.Item1; Task antecedentTask = tuple.Item2; @@ -662,7 +665,7 @@ namespace System.Threading.Tasks { // If we have an exception related to our CancellationToken, then we need to subtract ourselves // from our parent before throwing it. - Task parent = m_contingentProperties?.m_parent; + Task? parent = m_contingentProperties?.m_parent; if ((parent != null) && ((Options & TaskCreationOptions.AttachedToParent) != 0) && ((parent.Options & TaskCreationOptions.DenyChildAttach) == 0)) @@ -678,8 +681,7 @@ namespace System.Threading.Tasks { get { - Delegate d = m_action; - return d != null ? d.Method.ToString() : "{null}"; + return m_action?.Method.ToString() ?? "{null}"; } } @@ -787,7 +789,7 @@ namespace System.Threading.Tasks /// <summary>Returns true if any of the supplied tasks require wait notification.</summary> /// <param name="tasks">The tasks to check.</param> /// <returns>true if any of the tasks require notification; otherwise, false.</returns> - internal static bool AnyTaskRequiresNotifyDebuggerOfWaitCompletion(Task[] tasks) + internal static bool AnyTaskRequiresNotifyDebuggerOfWaitCompletion(Task?[] tasks) { Debug.Assert(tasks != null, "Expected non-null array of tasks"); foreach (var task in tasks) @@ -871,8 +873,8 @@ namespace System.Threading.Tasks { m_stateFlags |= Task.TASK_STATE_TASKSCHEDULED_WAS_FIRED; - Task currentTask = Task.InternalCurrent; - Task parentTask = m_contingentProperties?.m_parent; + Task? currentTask = Task.InternalCurrent; + Task? parentTask = m_contingentProperties?.m_parent; TplEventSource.Log.TaskScheduled(ts.Id, currentTask == null ? 0 : currentTask.Id, this.Id, parentTask == null ? 0 : parentTask.Id, (int)this.Options); } @@ -1049,7 +1051,7 @@ namespace System.Threading.Tasks ThrowHelper.ThrowArgumentNullException(ExceptionArgument.scheduler); } - InternalRunSynchronously(scheduler, waitForCompletion: true); + InternalRunSynchronously(scheduler!, waitForCompletion: true); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } // @@ -1158,7 +1160,7 @@ namespace System.Threading.Tasks // Implicitly converts action to object and handles the meat of the StartNew() logic. internal static Task InternalStartNew( - Task creatingTask, Delegate action, object state, CancellationToken cancellationToken, TaskScheduler scheduler, + Task? creatingTask, Delegate action, object? state, CancellationToken cancellationToken, TaskScheduler scheduler, TaskCreationOptions options, InternalTaskOptions internalOptions) { // Validate arguments. @@ -1227,7 +1229,7 @@ namespace System.Threading.Tasks { get { - Task currentTask = InternalCurrent; + Task? currentTask = InternalCurrent; if (currentTask != null) return currentTask.Id; else @@ -1239,7 +1241,7 @@ namespace System.Threading.Tasks /// Gets the <see cref="Task">Task</see> instance currently executing, or /// null if none exists. /// </summary> - internal static Task InternalCurrent + internal static Task? InternalCurrent { get { return t_currentTask; } } @@ -1250,7 +1252,7 @@ namespace System.Threading.Tasks /// </summary> /// <param name="creationOptions">The options to check.</param> /// <returns>The current task if there is one and if AttachToParent is in the options; otherwise, null.</returns> - internal static Task InternalCurrentIfAttached(TaskCreationOptions creationOptions) + internal static Task? InternalCurrentIfAttached(TaskCreationOptions creationOptions) { return (creationOptions & TaskCreationOptions.AttachedToParent) != 0 ? InternalCurrent : null; } @@ -1267,11 +1269,11 @@ namespace System.Threading.Tasks /// or in accesses to the <see cref="Exception"/> property. Any exceptions not observed by the time /// the Task instance is garbage collected will be propagated on the finalizer thread. /// </remarks> - public AggregateException Exception + public AggregateException? Exception { get { - AggregateException e = null; + AggregateException? e = null; // If you're faulted, retrieve the exception(s) if (IsFaulted) e = GetExceptions(false); @@ -1355,7 +1357,7 @@ namespace System.Threading.Tasks /// <returns>The initialized contingent properties object.</returns> internal ContingentProperties EnsureContingentPropertiesInitialized() { - return LazyInitializer.EnsureInitialized(ref m_contingentProperties, () => new ContingentProperties()); + return LazyInitializer.EnsureInitialized(ref m_contingentProperties, () => new ContingentProperties())!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } /// <summary> @@ -1460,7 +1462,7 @@ namespace System.Threading.Tasks /// Gets the state object supplied when the <see cref="Task">Task</see> was created, /// or null if none was supplied. /// </summary> - public object AsyncState + public object? AsyncState { get { return m_stateObject; } } @@ -1480,7 +1482,7 @@ namespace System.Threading.Tasks /// <summary> /// Provides access to the TaskScheduler responsible for executing this Task. /// </summary> - internal TaskScheduler ExecutingTaskScheduler + internal TaskScheduler? ExecutingTaskScheduler { get { return m_taskScheduler; } } @@ -1524,13 +1526,13 @@ namespace System.Threading.Tasks } } - return contingentProps.m_completionEvent; + return contingentProps.m_completionEvent!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } } /// <summary> - /// The property formerly known as IsFaulted. + /// Whether an exception has been stored into the task. /// </summary> internal bool ExceptionRecorded { @@ -1563,7 +1565,7 @@ namespace System.Threading.Tasks /// If the TASK_STATE_EXECUTIONCONTEXT_IS_NULL flag is set, this means ExecutionContext.Capture returned null, otherwise /// If the captured context is the default, nothing is saved, otherwise the m_contingentProperties inflates to save the context /// </summary> - internal ExecutionContext CapturedContext + internal ExecutionContext? CapturedContext { get { @@ -1716,6 +1718,7 @@ namespace System.Threading.Tasks if (AsyncCausalityTracer.LoggingOn && (Options & (TaskCreationOptions)InternalTaskOptions.ContinuationTask) == 0) { //For all other task than TaskContinuations we want to log. TaskContinuations log in their constructor + Debug.Assert(m_action != null, "Must have a delegate to be in ScheduleAndStart"); AsyncCausalityTracer.TraceOperationCreation(this, "Task: " + m_action.Method.Name); } @@ -1813,7 +1816,7 @@ namespace System.Threading.Tasks lock (props) { - props.m_exceptionsHolder.Add(exceptionObject, representsCancellation); + props.m_exceptionsHolder!.Add(exceptionObject, representsCancellation); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } } @@ -1823,7 +1826,7 @@ namespace System.Threading.Tasks /// </summary> /// <param name="includeTaskCanceledExceptions">Whether to include a TCE if cancelled.</param> /// <returns>An aggregate exception, or null if no exceptions have been caught.</returns> - private AggregateException GetExceptions(bool includeTaskCanceledExceptions) + private AggregateException? GetExceptions(bool includeTaskCanceledExceptions) { // // WARNING: The Task/Task<TResult>/TaskCompletionSource classes @@ -1861,7 +1864,7 @@ namespace System.Threading.Tasks // // We'll lazily create a TCE if the task has been canceled. - Exception canceledException = null; + Exception? canceledException = null; if (includeTaskCanceledExceptions && IsCanceled) { // Backcompat: @@ -1877,7 +1880,7 @@ namespace System.Threading.Tasks { // There are exceptions; get the aggregate and optionally add the canceled // exception to the aggregate (if applicable). - Debug.Assert(m_contingentProperties != null); // ExceptionRecorded ==> m_contingentProperties != null + Debug.Assert(m_contingentProperties != null && m_contingentProperties.m_exceptionsHolder != null, "ExceptionRecorded should imply this"); // No need to lock around this, as other logic prevents the consumption of exceptions // before they have been completely processed. @@ -1898,13 +1901,13 @@ namespace System.Threading.Tasks bool exceptionsAvailable = IsFaulted && ExceptionRecorded; Debug.Assert(exceptionsAvailable, "Must only be used when the task has faulted with exceptions."); return exceptionsAvailable ? - m_contingentProperties.m_exceptionsHolder.GetExceptionDispatchInfos() : + m_contingentProperties!.m_exceptionsHolder!.GetExceptionDispatchInfos() : new ReadOnlyCollection<ExceptionDispatchInfo>(new ExceptionDispatchInfo[0]); } /// <summary>Gets the ExceptionDispatchInfo containing the OperationCanceledException for this task.</summary> /// <returns>The ExceptionDispatchInfo. May be null if no OCE was stored for the task.</returns> - internal ExceptionDispatchInfo GetCancellationExceptionDispatchInfo() + internal ExceptionDispatchInfo? GetCancellationExceptionDispatchInfo() { Debug.Assert(IsCanceled, "Must only be used when the task has canceled."); return Volatile.Read(ref m_contingentProperties)?.m_exceptionsHolder?.GetCancellationExceptionDispatchInfo(); // may be null @@ -1917,7 +1920,7 @@ namespace System.Threading.Tasks { Debug.Assert(IsCompleted, "ThrowIfExceptional(): Expected IsCompleted == true"); - Exception exception = GetExceptions(includeTaskCanceledExceptions); + Exception? exception = GetExceptions(includeTaskCanceledExceptions); if (exception != null) { UpdateExceptionObservedStatus(); @@ -1928,7 +1931,7 @@ namespace System.Threading.Tasks /// <summary>Throws the exception on the ThreadPool.</summary> /// <param name="exception">The exception to propagate.</param> /// <param name="targetContext">The target context on which to propagate the exception. Null to use the ThreadPool.</param> - internal static void ThrowAsync(Exception exception, SynchronizationContext targetContext) + internal static void ThrowAsync(Exception exception, SynchronizationContext? targetContext) { // Capture the exception into an ExceptionDispatchInfo so that its // stack trace and Watson bucket info will be preserved @@ -1940,7 +1943,7 @@ namespace System.Threading.Tasks try { // Post the throwing of the exception to that context, and return. - targetContext.Post(state => ((ExceptionDispatchInfo)state).Throw(), edi); + targetContext.Post(state => ((ExceptionDispatchInfo)state!).Throw(), edi); return; } catch (Exception postException) @@ -1962,7 +1965,7 @@ namespace System.Threading.Tasks #endif // Propagate the exception(s) on the ThreadPool - ThreadPool.QueueUserWorkItem(state => ((ExceptionDispatchInfo)state).Throw(), edi); + ThreadPool.QueueUserWorkItem(state => ((ExceptionDispatchInfo)state!).Throw(), edi); #endif // CORERT } @@ -1980,7 +1983,7 @@ namespace System.Threading.Tasks /// </summary> internal void UpdateExceptionObservedStatus() { - Task parent = m_contingentProperties?.m_parent; + Task? parent = m_contingentProperties?.m_parent; if ((parent != null) && ((Options & TaskCreationOptions.AttachedToParent) != 0) && ((parent.CreationOptions & TaskCreationOptions.DenyChildAttach) == 0) @@ -2048,7 +2051,7 @@ namespace System.Threading.Tasks } else { - ContingentProperties props = m_contingentProperties; + ContingentProperties props = m_contingentProperties!; // Count of 1 => either all children finished, or there were none. Safe to complete ourselves // without paying the price of an Interlocked.Decrement. @@ -2075,7 +2078,7 @@ namespace System.Threading.Tasks // Now is the time to prune exceptional children. We'll walk the list and removes the ones whose exceptions we might have observed after they threw. // we use a local variable for exceptional children here because some other thread may be nulling out m_contingentProperties.m_exceptionalChildren - List<Task> exceptionalChildren = props.m_exceptionalChildren; + List<Task>? exceptionalChildren = props.m_exceptionalChildren; if (exceptionalChildren != null) { lock (exceptionalChildren) @@ -2096,7 +2099,7 @@ namespace System.Threading.Tasks // At this point, the task is done executing and waiting for its children, // we can transition our task to a completion state. - ContingentProperties cp = Volatile.Read(ref m_contingentProperties); + ContingentProperties? cp = Volatile.Read(ref m_contingentProperties); if (cp != null) { AddExceptionsFromChildren(cp); @@ -2170,7 +2173,7 @@ namespace System.Threading.Tasks // continuations hold onto the task, and therefore are keeping it alive. m_action = null; - ContingentProperties cp = m_contingentProperties; + ContingentProperties? cp = m_contingentProperties; if (cp != null) { // Similarly, null out any ExecutionContext we may have captured, @@ -2188,7 +2191,7 @@ namespace System.Threading.Tasks internal void NotifyParentIfPotentiallyAttachedTask() { - Task parent = m_contingentProperties?.m_parent; + Task? parent = m_contingentProperties?.m_parent; if (parent != null && ((parent.CreationOptions & TaskCreationOptions.DenyChildAttach) == 0) && (((TaskCreationOptions)(m_stateFlags & OptionsMask)) & TaskCreationOptions.AttachedToParent) != 0) @@ -2213,7 +2216,7 @@ namespace System.Threading.Tasks if (childTask.IsFaulted && !childTask.IsExceptionObservedByParent) { // Lazily initialize the child exception list - if (props.m_exceptionalChildren == null) + if (props!.m_exceptionalChildren == null) { Interlocked.CompareExchange(ref props.m_exceptionalChildren, new List<Task>(), null); } @@ -2222,7 +2225,7 @@ namespace System.Threading.Tasks // multiple times for the same task. In that case, AddExceptionsFromChildren() could be nulling m_exceptionalChildren // out at the same time that we're processing it, resulting in a NullReferenceException here. We'll protect // ourselves by caching m_exceptionChildren in a local variable. - List<Task> tmp = props.m_exceptionalChildren; + List<Task>? tmp = props.m_exceptionalChildren; if (tmp != null) { lock (tmp) @@ -2232,7 +2235,7 @@ namespace System.Threading.Tasks } } - if (Interlocked.Decrement(ref props.m_completionCountdown) == 0) + if (Interlocked.Decrement(ref props!.m_completionCountdown) == 0) { // This call came from the final child to complete, and apparently we have previously given up this task's right to complete itself. // So we need to invoke the final finish stage. @@ -2253,7 +2256,7 @@ namespace System.Threading.Tasks // simultaneously on the same task from two different contexts. This can result in m_exceptionalChildren // being nulled out while it is being processed, which could lead to a NullReferenceException. To // protect ourselves, we'll cache m_exceptionalChildren in a local variable. - List<Task> exceptionalChildren = props.m_exceptionalChildren; + List<Task>? exceptionalChildren = props.m_exceptionalChildren; if (exceptionalChildren != null) { @@ -2268,7 +2271,7 @@ namespace System.Threading.Tasks Debug.Assert(task.IsCompleted, "Expected all tasks in list to be completed"); if (task.IsFaulted && !task.IsExceptionObservedByParent) { - TaskExceptionHolder exceptionHolder = Volatile.Read(ref task.m_contingentProperties).m_exceptionsHolder; + TaskExceptionHolder? exceptionHolder = Volatile.Read(ref task.m_contingentProperties)!.m_exceptionsHolder; Debug.Assert(exceptionHolder != null); // No locking necessary since child task is finished adding exceptions @@ -2322,7 +2325,7 @@ namespace System.Threading.Tasks /// </summary> internal virtual void ExecuteFromThreadPool(Thread threadPoolThread) => ExecuteEntryUnsafe(threadPoolThread); - internal void ExecuteEntryUnsafe(Thread threadPoolThread) // used instead of ExecuteEntry() when we don't have to worry about double-execution prevent + internal void ExecuteEntryUnsafe(Thread? threadPoolThread) // used instead of ExecuteEntry() when we don't have to worry about double-execution prevent { // Remember that we started running the task delegate. m_stateFlags |= TASK_STATE_DELEGATE_INVOKED; @@ -2350,10 +2353,10 @@ namespace System.Threading.Tasks } // A trick so we can refer to the TLS slot with a byref. - private void ExecuteWithThreadLocal(ref Task currentTaskSlot, Thread threadPoolThread = null) + private void ExecuteWithThreadLocal(ref Task? currentTaskSlot, Thread? threadPoolThread = null) { // Remember the current task so we can restore it after running, and then - Task previousTask = currentTaskSlot; + Task? previousTask = currentTaskSlot; // ETW event for Task Started var log = TplEventSource.Log; @@ -2365,7 +2368,7 @@ namespace System.Threading.Tasks EventSource.SetCurrentThreadActivityId(TplEventSource.CreateGuidForTaskID(this.Id), out savedActivityID); // previousTask holds the actual "current task" we want to report in the event if (previousTask != null) - log.TaskStarted(previousTask.m_taskScheduler.Id, previousTask.Id, this.Id); + log.TaskStarted(previousTask.m_taskScheduler!.Id, previousTask.Id, this.Id); else log.TaskStarted(TaskScheduler.Current.Id, 0, this.Id); } @@ -2382,7 +2385,7 @@ namespace System.Threading.Tasks // Execute the task body try { - ExecutionContext ec = CapturedContext; + ExecutionContext? ec = CapturedContext; if (ec == null) { // No context, just run the task directly. @@ -2421,7 +2424,7 @@ namespace System.Threading.Tasks { // previousTask holds the actual "current task" we want to report in the event if (previousTask != null) - log.TaskCompleted(previousTask.m_taskScheduler.Id, previousTask.Id, this.Id, IsFaulted); + log.TaskCompleted(previousTask.m_taskScheduler!.Id, previousTask.Id, this.Id, IsFaulted); else log.TaskCompleted(TaskScheduler.Current.Id, 0, this.Id, IsFaulted); @@ -2451,7 +2454,7 @@ namespace System.Threading.Tasks return; } - if (m_action is Action<object> actionWithState) + if (m_action is Action<object?> actionWithState) { actionWithState(m_stateObject); return; @@ -2469,7 +2472,7 @@ namespace System.Threading.Tasks Debug.Assert(unhandledException != null); if (unhandledException is OperationCanceledException exceptionAsOce && IsCancellationRequested && - m_contingentProperties.m_cancellationToken == exceptionAsOce.CancellationToken) + m_contingentProperties!.m_cancellationToken == exceptionAsOce.CancellationToken) { // All conditions are satisfied for us to go into canceled state in Finish(). // Mark the acknowledgement. The exception is also stored to enable it to be @@ -2526,7 +2529,7 @@ namespace System.Threading.Tasks // Create the best AwaitTaskContinuation object given the request. // If this remains null by the end of the function, we can use the // continuationAction directly without wrapping it. - TaskContinuation tc = null; + TaskContinuation? tc = null; // If the user wants the continuation to run on the current "context" if there is one... if (continueOnCapturedContext) @@ -2605,7 +2608,7 @@ namespace System.Threading.Tasks // fall back to using the state machine's delegate. if (continueOnCapturedContext) { - SynchronizationContext syncCtx = SynchronizationContext.Current; + SynchronizationContext? syncCtx = SynchronizationContext.Current; if (syncCtx != null && syncCtx.GetType() != typeof(SynchronizationContext)) { var tc = new SynchronizationContextAwaitTaskContinuation(syncCtx, stateMachineBox.MoveNextAction, flowExecutionContext: false); @@ -2617,7 +2620,7 @@ namespace System.Threading.Tasks } else { - TaskScheduler scheduler = TaskScheduler.InternalCurrent; + TaskScheduler? scheduler = TaskScheduler.InternalCurrent; if (scheduler != null && scheduler != TaskScheduler.Default) { var tc = new TaskSchedulerAwaitTaskContinuation(scheduler, stateMachineBox.MoveNextAction, flowExecutionContext: false); @@ -2846,9 +2849,9 @@ namespace System.Threading.Tasks bool etwIsEnabled = log.IsEnabled(); if (etwIsEnabled) { - Task currentTask = Task.InternalCurrent; + Task? currentTask = Task.InternalCurrent; log.TaskWaitBegin( - (currentTask != null ? currentTask.m_taskScheduler.Id : TaskScheduler.Default.Id), (currentTask != null ? currentTask.Id : 0), + (currentTask != null ? currentTask.m_taskScheduler!.Id : TaskScheduler.Default.Id), (currentTask != null ? currentTask.Id : 0), this.Id, TplEventSource.TaskWaitBehavior.Synchronous, 0); } @@ -2877,10 +2880,10 @@ namespace System.Threading.Tasks // ETW event for Task Wait End if (etwIsEnabled) { - Task currentTask = Task.InternalCurrent; + Task? currentTask = Task.InternalCurrent; if (currentTask != null) { - log.TaskWaitEnd(currentTask.m_taskScheduler.Id, currentTask.Id, this.Id); + log.TaskWaitEnd(currentTask.m_taskScheduler!.Id, currentTask.Id, this.Id); } else { @@ -2999,12 +3002,12 @@ namespace System.Threading.Tasks bool bPopSucceeded = false; bool mustCleanup = false; - TaskSchedulerException tse = null; + TaskSchedulerException? tse = null; // If started, and running in a task context, we can try to pop the chore. if ((m_stateFlags & TASK_STATE_STARTED) != 0) { - TaskScheduler ts = m_taskScheduler; + TaskScheduler? ts = m_taskScheduler; try { @@ -3095,7 +3098,7 @@ namespace System.Threading.Tasks RecordInternalCancellationRequest(); Debug.Assert((Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0, "Task.RecordInternalCancellationRequest(CancellationToken) only valid for promise-style task"); - Debug.Assert(m_contingentProperties.m_cancellationToken == default); + Debug.Assert(m_contingentProperties!.m_cancellationToken == default); // Store the supplied cancellation token as this task's token. // Waiting on this task will then result in an OperationCanceledException containing this token. @@ -3108,7 +3111,7 @@ namespace System.Threading.Tasks // Breaks out logic for recording a cancellation request // This overload should only be used for promise tasks where no cancellation token // was supplied when the task was created. - internal void RecordInternalCancellationRequest(CancellationToken tokenToRecord, object cancellationException) + internal void RecordInternalCancellationRequest(CancellationToken tokenToRecord, object? cancellationException) { RecordInternalCancellationRequest(tokenToRecord); @@ -3184,7 +3187,7 @@ namespace System.Threading.Tasks TASK_STATE_COMPLETION_RESERVED | TASK_STATE_RAN_TO_COMPLETION, TASK_STATE_COMPLETION_RESERVED | TASK_STATE_RAN_TO_COMPLETION | TASK_STATE_FAULTED | TASK_STATE_CANCELED)) { - ContingentProperties props = m_contingentProperties; + ContingentProperties? props = m_contingentProperties; if (props != null) { NotifyParentIfPotentiallyAttachedTask(); @@ -3252,7 +3255,7 @@ namespace System.Threading.Tasks // If the tokenToRecord is not None, it will be stored onto the task. // If the OperationCanceledException is not null, it will be stored into the task's exception holder. // This method is only valid for promise tasks. - internal bool TrySetCanceled(CancellationToken tokenToRecord, object cancellationException) + internal bool TrySetCanceled(CancellationToken tokenToRecord, object? cancellationException) { Debug.Assert(m_action == null, "Task<T>.TrySetCanceled(): non-null m_action"); Debug.Assert( @@ -3296,7 +3299,7 @@ namespace System.Threading.Tasks // Atomically store the fact that this task is completing. From this point on, the adding of continuations will // result in the continuations being run/launched directly rather than being added to the continuation list. // Then if we grabbed any continuations, run them. - object continuationObject = Interlocked.Exchange(ref m_continuationObject, s_taskCompletionSentinel); + object? continuationObject = Interlocked.Exchange(ref m_continuationObject, s_taskCompletionSentinel); if (continuationObject != null) { RunContinuations(continuationObject); @@ -3352,7 +3355,7 @@ namespace System.Threading.Tasks } // Not a single; it must be a list. - List<object> continuations = (List<object>)continuationObject; + List<object?> continuations = (List<object?>)continuationObject; // // Begin processing of continuation list @@ -3384,7 +3387,7 @@ namespace System.Threading.Tasks // and Action delegates, which are all by default implicitly synchronous. for (int i = 0; i < continuationCount; i++) { - object currentContinuation = continuations[i]; + object? currentContinuation = continuations[i]; if (currentContinuation == null) { continue; @@ -3611,13 +3614,13 @@ namespace System.Threading.Tasks CreationOptionsFromContinuationOptions(continuationOptions, out creationOptions, out internalOptions); Task continuationTask = new ContinuationTaskFromTask( - this, continuationAction, null, + this, continuationAction!, null, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 creationOptions, internalOptions ); // Register the continuation. If synchronous execution is requested, this may // actually invoke the continuation before returning. - ContinueWithCore(continuationTask, scheduler, cancellationToken, continuationOptions); + ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 return continuationTask; } @@ -3642,7 +3645,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ArgumentNullException"> /// The <paramref name="continuationAction"/> argument is null. /// </exception> - public Task ContinueWith(Action<Task, object> continuationAction, object state) + public Task ContinueWith(Action<Task, object?> continuationAction, object? state) { return ContinueWith(continuationAction, state, TaskScheduler.Current, default, TaskContinuationOptions.None); } @@ -3668,7 +3671,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see> /// has already been disposed. /// </exception> - public Task ContinueWith(Action<Task, object> continuationAction, object state, CancellationToken cancellationToken) + public Task ContinueWith(Action<Task, object?> continuationAction, object? state, CancellationToken cancellationToken) { return ContinueWith(continuationAction, state, TaskScheduler.Current, cancellationToken, TaskContinuationOptions.None); } @@ -3696,7 +3699,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ArgumentNullException"> /// The <paramref name="scheduler"/> argument is null. /// </exception> - public Task ContinueWith(Action<Task, object> continuationAction, object state, TaskScheduler scheduler) + public Task ContinueWith(Action<Task, object?> continuationAction, object? state, TaskScheduler scheduler) { return ContinueWith(continuationAction, state, scheduler, default, TaskContinuationOptions.None); } @@ -3730,7 +3733,7 @@ namespace System.Threading.Tasks /// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see /// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>. /// </exception> - public Task ContinueWith(Action<Task, object> continuationAction, object state, TaskContinuationOptions continuationOptions) + public Task ContinueWith(Action<Task, object?> continuationAction, object? state, TaskContinuationOptions continuationOptions) { return ContinueWith(continuationAction, state, TaskScheduler.Current, default, continuationOptions); } @@ -3774,14 +3777,14 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see> /// has already been disposed. /// </exception> - public Task ContinueWith(Action<Task, object> continuationAction, object state, CancellationToken cancellationToken, + public Task ContinueWith(Action<Task, object?> continuationAction, object? state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { return ContinueWith(continuationAction, state, scheduler, cancellationToken, continuationOptions); } // Same as the above overload, just with a stack mark parameter. - private Task ContinueWith(Action<Task, object> continuationAction, object state, TaskScheduler scheduler, + private Task ContinueWith(Action<Task, object?> continuationAction, object? state, TaskScheduler scheduler, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions) { // Throw on continuation with null action @@ -3801,13 +3804,13 @@ namespace System.Threading.Tasks CreationOptionsFromContinuationOptions(continuationOptions, out creationOptions, out internalOptions); Task continuationTask = new ContinuationTaskFromTask( - this, continuationAction, state, + this, continuationAction!, state, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 creationOptions, internalOptions ); // Register the continuation. If synchronous execution is requested, this may // actually invoke the continuation before returning. - ContinueWithCore(continuationTask, scheduler, cancellationToken, continuationOptions); + ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 return continuationTask; } @@ -4004,13 +4007,13 @@ namespace System.Threading.Tasks CreationOptionsFromContinuationOptions(continuationOptions, out creationOptions, out internalOptions); Task<TResult> continuationTask = new ContinuationResultTaskFromTask<TResult>( - this, continuationFunction, null, + this, continuationFunction!, null, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 creationOptions, internalOptions ); // Register the continuation. If synchronous execution is requested, this may // actually invoke the continuation before returning. - ContinueWithCore(continuationTask, scheduler, cancellationToken, continuationOptions); + ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 return continuationTask; } @@ -4038,7 +4041,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ArgumentNullException"> /// The <paramref name="continuationFunction"/> argument is null. /// </exception> - public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state) + public Task<TResult> ContinueWith<TResult>(Func<Task, object?, TResult> continuationFunction, object? state) { return ContinueWith<TResult>(continuationFunction, state, TaskScheduler.Current, default, TaskContinuationOptions.None); @@ -4069,7 +4072,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see> /// has already been disposed. /// </exception> - public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, CancellationToken cancellationToken) + public Task<TResult> ContinueWith<TResult>(Func<Task, object?, TResult> continuationFunction, object? state, CancellationToken cancellationToken) { return ContinueWith<TResult>(continuationFunction, state, TaskScheduler.Current, cancellationToken, TaskContinuationOptions.None); } @@ -4100,7 +4103,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ArgumentNullException"> /// The <paramref name="scheduler"/> argument is null. /// </exception> - public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, TaskScheduler scheduler) + public Task<TResult> ContinueWith<TResult>(Func<Task, object?, TResult> continuationFunction, object? state, TaskScheduler scheduler) { return ContinueWith<TResult>(continuationFunction, state, scheduler, default, TaskContinuationOptions.None); } @@ -4137,7 +4140,7 @@ namespace System.Threading.Tasks /// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see /// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>. /// </exception> - public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, TaskContinuationOptions continuationOptions) + public Task<TResult> ContinueWith<TResult>(Func<Task, object?, TResult> continuationFunction, object? state, TaskContinuationOptions continuationOptions) { return ContinueWith<TResult>(continuationFunction, state, TaskScheduler.Current, default, continuationOptions); } @@ -4184,14 +4187,14 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see> /// has already been disposed. /// </exception> - public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, CancellationToken cancellationToken, + public Task<TResult> ContinueWith<TResult>(Func<Task, object?, TResult> continuationFunction, object? state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) { return ContinueWith<TResult>(continuationFunction, state, scheduler, cancellationToken, continuationOptions); } // Same as the above overload, just with a stack mark parameter. - private Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, TaskScheduler scheduler, + private Task<TResult> ContinueWith<TResult>(Func<Task, object?, TResult> continuationFunction, object? state, TaskScheduler scheduler, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions) { // Throw on continuation with null function @@ -4211,13 +4214,13 @@ namespace System.Threading.Tasks CreationOptionsFromContinuationOptions(continuationOptions, out creationOptions, out internalOptions); Task<TResult> continuationTask = new ContinuationResultTaskFromTask<TResult>( - this, continuationFunction, state, + this, continuationFunction!, state, // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 creationOptions, internalOptions ); // Register the continuation. If synchronous execution is requested, this may // actually invoke the continuation before returning. - ContinueWithCore(continuationTask, scheduler, cancellationToken, continuationOptions); + ContinueWithCore(continuationTask, scheduler!, cancellationToken, continuationOptions); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 return continuationTask; } @@ -4386,13 +4389,13 @@ namespace System.Threading.Tasks { Debug.Assert(tc != null, "Expected non-null tc object in AddTaskContinuationComplex"); - object oldValue = m_continuationObject; + object? oldValue = m_continuationObject; // Logic for the case where we were previously storing a single continuation - if ((oldValue != s_taskCompletionSentinel) && (!(oldValue is List<object>))) + if ((oldValue != s_taskCompletionSentinel) && (!(oldValue is List<object?>))) { // Construct a new TaskContinuation list - List<object> newList = new List<object>(); + List<object?> newList = new List<object?>(); // Add in the old single value newList.Add(oldValue); @@ -4407,7 +4410,7 @@ namespace System.Threading.Tasks // m_continuationObject is guaranteed at this point to be either a List or // s_taskCompletionSentinel. - List<object> list = m_continuationObject as List<object>; + List<object?>? list = m_continuationObject as List<object?>; Debug.Assert((list != null) || (m_continuationObject == s_taskCompletionSentinel), "Expected m_continuationObject to be list or sentinel"); @@ -4469,21 +4472,21 @@ namespace System.Threading.Tasks { // We need to snap a local reference to m_continuations since reading a volatile object is more costly. // Also to prevent the value to be changed as result of a race condition with another method. - object continuationsLocalRef = m_continuationObject; + object? continuationsLocalRef = m_continuationObject; // Task is completed. Nothing to do here. if (continuationsLocalRef == s_taskCompletionSentinel) return; - if (!(continuationsLocalRef is List<object> continuationsLocalListRef)) + if (!(continuationsLocalRef is List<object?> continuationsLocalListRef)) { // This is not a list. If we have a single object (the one we want to remove) we try to replace it with an empty list. // Note we cannot go back to a null state, since it will mess up the AddTaskContinuation logic. - if (Interlocked.CompareExchange(ref m_continuationObject, new List<object>(), continuationObject) != continuationObject) + if (Interlocked.CompareExchange(ref m_continuationObject, new List<object?>(), continuationObject) != continuationObject) { // If we fail it means that either AddContinuationComplex won the race condition and m_continuationObject is now a List // that contains the element we want to remove. Or FinishContinuations set the s_taskCompletionSentinel. // So we should try to get a list one more time - continuationsLocalListRef = m_continuationObject as List<object>; + continuationsLocalListRef = m_continuationObject as List<object?>; } else { @@ -4711,9 +4714,9 @@ namespace System.Threading.Tasks // We make sure that the exception behavior of Task.Wait() is replicated the same for tasks handled in either of these codepaths // - List<Exception> exceptions = null; - List<Task> waitedOnTaskList = null; - List<Task> notificationTasks = null; + List<Exception>? exceptions = null; + List<Task>? waitedOnTaskList = null; + List<Task>? notificationTasks = null; // If any of the waited-upon tasks end as Faulted or Canceled, set these to true. bool exceptionSeen = false, cancellationSeen = false; @@ -4721,7 +4724,7 @@ namespace System.Threading.Tasks bool returnValue = true; // Collects incomplete tasks in "waitedOnTaskList" - for (int i = tasks.Length - 1; i >= 0; i--) + for (int i = tasks!.Length - 1; i >= 0; i--) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { Task task = tasks[i]; @@ -4730,7 +4733,7 @@ namespace System.Threading.Tasks ThrowHelper.ThrowArgumentException(ExceptionResource.Task_WaitMulti_NullTask, ExceptionArgument.tasks); } - bool taskIsCompleted = task.IsCompleted; + bool taskIsCompleted = task!.IsCompleted; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 if (!taskIsCompleted) { // try inlining the task only if we have an infinite timeout and an empty cancellation token @@ -4819,7 +4822,7 @@ namespace System.Threading.Tasks /// <param name="item">The item to add.</param> /// <param name="list">The list.</param> /// <param name="initSize">The size to which to initialize the list if the list is null.</param> - private static void AddToList<T>(T item, ref List<T> list, int initSize) + private static void AddToList<T>(T item, ref List<T>? list, int initSize) { if (list == null) list = new List<T>(initSize); list.Add(item); @@ -4897,9 +4900,9 @@ namespace System.Threading.Tasks /// If the completed task is canceled or it has other exceptions, here we will add those /// into the passed in exception list (which will be lazily initialized here). /// </summary> - internal static void AddExceptionsForCompletedTask(ref List<Exception> exceptions, Task t) + internal static void AddExceptionsForCompletedTask(ref List<Exception>? exceptions, Task t) { - AggregateException ex = t.GetExceptions(true); + AggregateException? ex = t.GetExceptions(true); if (ex != null) { // make sure the task's exception observed status is set appropriately @@ -5086,7 +5089,7 @@ namespace System.Threading.Tasks // Make a pass through the loop to check for any tasks that may have // already been completed, and to verify that no tasks are null. - for (int taskIndex = 0; taskIndex < tasks.Length; taskIndex++) + for (int taskIndex = 0; taskIndex < tasks!.Length; taskIndex++) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { Task task = tasks[taskIndex]; @@ -5095,7 +5098,7 @@ namespace System.Threading.Tasks ThrowHelper.ThrowArgumentException(ExceptionResource.Task_WaitMulti_NullTask, ExceptionArgument.tasks); } - if (signaledTaskIndex == -1 && task.IsCompleted) + if (signaledTaskIndex == -1 && task!.IsCompleted) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { // We found our first completed task. Store it, but we can't just return here, // as we still need to validate the whole array for nulls. @@ -5147,7 +5150,7 @@ namespace System.Threading.Tasks if (exception == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception); var task = new Task(); - bool succeeded = task.TrySetException(exception); + bool succeeded = task.TrySetException(exception!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 Debug.Assert(succeeded, "This should always succeed on a new task."); return task; } @@ -5161,7 +5164,7 @@ namespace System.Threading.Tasks if (exception == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception); var task = new Task<TResult>(); - bool succeeded = task.TrySetException(exception); + bool succeeded = task.TrySetException(exception!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 Debug.Assert(succeeded, "This should always succeed on a new task."); return task; } @@ -5184,7 +5187,7 @@ namespace System.Threading.Tasks { if (!cancellationToken.IsCancellationRequested) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.cancellationToken); - return new Task<TResult>(true, default, TaskCreationOptions.None, cancellationToken); + return new Task<TResult>(true, default!, TaskCreationOptions.None, cancellationToken); // TODO-NULLABLE-GENERIC } /// <summary>Creates a <see cref="Task"/> that's completed due to cancellation with the specified exception.</summary> @@ -5292,7 +5295,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ArgumentNullException"> /// The <paramref name="function"/> parameter was null. /// </exception> - public static Task Run(Func<Task> function) + public static Task Run(Func<Task?> function) { return Run(function, default); } @@ -5311,7 +5314,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ObjectDisposedException"> /// The <see cref="T:System.CancellationTokenSource"/> associated with <paramref name="cancellationToken"/> was disposed. /// </exception> - public static Task Run(Func<Task> function, CancellationToken cancellationToken) + public static Task Run(Func<Task?> function, CancellationToken cancellationToken) { // Check arguments if (function == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.function); @@ -5321,7 +5324,7 @@ namespace System.Threading.Tasks return Task.FromCanceled(cancellationToken); // Kick off initial Task, which will call the user-supplied function and yield a Task. - Task<Task> task1 = Task<Task>.Factory.StartNew(function, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + Task<Task?> task1 = Task<Task?>.Factory.StartNew(function!, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 // Create a promise-style Task to be used as a proxy for the operation // Set lookForOce == true so that unwrap logic can be on the lookout for OCEs thrown as faults from task1, to support in-delegate cancellation. @@ -5340,7 +5343,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ArgumentNullException"> /// The <paramref name="function"/> parameter was null. /// </exception> - public static Task<TResult> Run<TResult>(Func<Task<TResult>> function) + public static Task<TResult> Run<TResult>(Func<Task<TResult>?> function) { return Run(function, default); } @@ -5356,7 +5359,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.ArgumentNullException"> /// The <paramref name="function"/> parameter was null. /// </exception> - public static Task<TResult> Run<TResult>(Func<Task<TResult>> function, CancellationToken cancellationToken) + public static Task<TResult> Run<TResult>(Func<Task<TResult>?> function, CancellationToken cancellationToken) { // Check arguments if (function == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.function); @@ -5366,7 +5369,7 @@ namespace System.Threading.Tasks return Task.FromCanceled<TResult>(cancellationToken); // Kick off initial Task, which will call the user-supplied function and yield a Task. - Task<Task<TResult>> task1 = Task<Task<TResult>>.Factory.StartNew(function, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + Task<Task<TResult>?> task1 = Task<Task<TResult>?>.Factory.StartNew(function!, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 // Create a promise-style Task to be used as a proxy for the operation // Set lookForOce == true so that unwrap logic can be on the lookout for OCEs thrown as faults from task1, to support in-delegate cancellation. @@ -5475,7 +5478,7 @@ namespace System.Threading.Tasks /// <summary>Task that also stores the completion closure and logic for Task.Delay implementation.</summary> private class DelayPromise : Task { - private readonly TimerQueueTimer _timer; + private readonly TimerQueueTimer? _timer; internal DelayPromise(int millisecondsDelay) { @@ -5489,7 +5492,7 @@ namespace System.Threading.Tasks if (millisecondsDelay != Timeout.Infinite) // no need to create the timer if it's an infinite timeout { - _timer = new TimerQueueTimer(state => ((DelayPromise)state).CompleteTimedOut(), this, (uint)millisecondsDelay, Timeout.UnsignedInfinite, flowExecutionContext: false); + _timer = new TimerQueueTimer(state => ((DelayPromise)state!).CompleteTimedOut(), this, (uint)millisecondsDelay, Timeout.UnsignedInfinite, flowExecutionContext: false); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 if (IsCanceled) { // Handle rare race condition where cancellation occurs prior to our having created and stored the timer, in which case @@ -5528,7 +5531,7 @@ namespace System.Threading.Tasks Debug.Assert(token.CanBeCanceled); _token = token; - _registration = token.UnsafeRegister(state => ((DelayPromiseWithCancellation)state).CompleteCanceled(), this); + _registration = token.UnsafeRegister(state => ((DelayPromiseWithCancellation)state!).CompleteCanceled(), this); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } private void CompleteCanceled() @@ -5593,7 +5596,7 @@ namespace System.Threading.Tasks foreach (var task in tasks) { if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks); - taskArray[index++] = task; + taskArray[index++] = task!; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } return InternalWhenAll(taskArray); } @@ -5601,10 +5604,10 @@ namespace System.Threading.Tasks // Do some argument checking and convert tasks to a List (and later an array). if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks); List<Task> taskList = new List<Task>(); - foreach (Task task in tasks) + foreach (Task task in tasks!) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks); - taskList.Add(task); + taskList.Add(task!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } // Delegate the rest to InternalWhenAll() @@ -5643,7 +5646,7 @@ namespace System.Threading.Tasks // Do some argument checking and make a defensive copy of the tasks array if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks); - int taskCount = tasks.Length; + int taskCount = tasks!.Length; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 if (taskCount == 0) return InternalWhenAll(tasks); // Small optimization in the case of an empty array. Task[] tasksCopy = new Task[taskCount]; @@ -5651,7 +5654,7 @@ namespace System.Threading.Tasks { Task task = tasks[i]; if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks); - tasksCopy[i] = task; + tasksCopy[i] = task!; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } // The rest can be delegated to InternalWhenAll() @@ -5686,7 +5689,7 @@ namespace System.Threading.Tasks /// Stores all of the constituent tasks. Tasks clear themselves out of this /// array as they complete, but only if they don't have their wait notification bit set. /// </summary> - private readonly Task[] m_tasks; + private readonly Task?[] m_tasks; /// <summary>The number of tasks remaining to complete.</summary> private int m_count; @@ -5720,8 +5723,8 @@ namespace System.Threading.Tasks if (Interlocked.Decrement(ref m_count) == 0) { // Set up some accounting variables - List<ExceptionDispatchInfo> observedExceptions = null; - Task canceledTask = null; + List<ExceptionDispatchInfo>? observedExceptions = null; + Task? canceledTask = null; // Loop through antecedents: // If any one of them faults, the result will be faulted @@ -5837,7 +5840,7 @@ namespace System.Threading.Tasks foreach (var task in tasks) { if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks); - taskArray[index++] = task; + taskArray[index++] = task!; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } return InternalWhenAll<TResult>(taskArray); } @@ -5845,10 +5848,10 @@ namespace System.Threading.Tasks // Do some argument checking and convert tasks into a List (later an array) if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks); List<Task<TResult>> taskList = new List<Task<TResult>>(); - foreach (Task<TResult> task in tasks) + foreach (Task<TResult> task in tasks!) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks); - taskList.Add(task); + taskList.Add(task!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } // Delegate the rest to InternalWhenAll<TResult>(). @@ -5890,7 +5893,7 @@ namespace System.Threading.Tasks // Do some argument checking and make a defensive copy of the tasks array if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks); - int taskCount = tasks.Length; + int taskCount = tasks!.Length; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 if (taskCount == 0) return InternalWhenAll<TResult>(tasks); // small optimization in the case of an empty task array Task<TResult>[] tasksCopy = new Task<TResult>[taskCount]; @@ -5898,7 +5901,7 @@ namespace System.Threading.Tasks { Task<TResult> task = tasks[i]; if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks); - tasksCopy[i] = task; + tasksCopy[i] = task!; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } // Delegate the rest to InternalWhenAll<TResult>() @@ -5925,7 +5928,7 @@ namespace System.Threading.Tasks /// Stores all of the constituent tasks. Tasks clear themselves out of this /// array as they complete, but only if they don't have their wait notification bit set. /// </summary> - private readonly Task<T>[] m_tasks; + private readonly Task<T>?[] m_tasks; /// <summary>The number of tasks remaining to complete.</summary> private int m_count; @@ -5961,8 +5964,8 @@ namespace System.Threading.Tasks { // Set up some accounting variables T[] results = new T[m_tasks.Length]; - List<ExceptionDispatchInfo> observedExceptions = null; - Task canceledTask = null; + List<ExceptionDispatchInfo>? observedExceptions = null; + Task? canceledTask = null; // Loop through antecedents: // If any one of them faults, the result will be faulted @@ -5970,7 +5973,7 @@ namespace System.Threading.Tasks // If none fault or are canceled, then result will be RanToCompletion for (int i = 0; i < m_tasks.Length; i++) { - Task<T> task = m_tasks[i]; + Task<T>? task = m_tasks[i]; Debug.Assert(task != null, "Constituent task in WhenAll should never be null"); if (task.IsFaulted) @@ -6057,7 +6060,7 @@ namespace System.Threading.Tasks public static Task<Task> WhenAny(params Task[] tasks) { if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks); - if (tasks.Length == 0) + if (tasks!.Length == 0) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_EmptyTaskList, ExceptionArgument.tasks); } @@ -6070,7 +6073,7 @@ namespace System.Threading.Tasks { Task task = tasks[i]; if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks); - tasksCopy[i] = task; + tasksCopy[i] = task!; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } // Previously implemented CommonCWAnyLogic() can handle the rest @@ -6099,10 +6102,10 @@ namespace System.Threading.Tasks // Make a defensive copy, as the user may manipulate the tasks collection // after we return but before the WhenAny asynchronously completes. List<Task> taskList = new List<Task>(); - foreach (Task task in tasks) + foreach (Task task in tasks!) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { if (task == null) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_NullTask, ExceptionArgument.tasks); - taskList.Add(task); + taskList.Add(task!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } if (taskList.Count == 0) @@ -6183,7 +6186,7 @@ namespace System.Threading.Tasks #if PROJECTN [DependencyReductionRoot] #endif - internal virtual Delegate[] GetDelegateContinuationsForDebugger() + internal virtual Delegate[]? GetDelegateContinuationsForDebugger() { //Avoid an infinite loop by making sure the continuation object is not a reference to istelf. if (m_continuationObject != this) @@ -6192,7 +6195,7 @@ namespace System.Threading.Tasks return null; } - private static Delegate[] GetDelegatesFromContinuationObject(object continuationObject) + private static Delegate[]? GetDelegatesFromContinuationObject(object? continuationObject) { if (continuationObject != null) { @@ -6209,7 +6212,7 @@ namespace System.Threading.Tasks if (continuationObject is Task continuationTask) { Debug.Assert(continuationTask.m_action == null); - Delegate[] delegates = continuationTask.GetDelegateContinuationsForDebugger(); + Delegate[]? delegates = continuationTask.GetDelegateContinuationsForDebugger(); if (delegates != null) return delegates; } @@ -6221,10 +6224,10 @@ namespace System.Threading.Tasks return new Delegate[] { new Action<Task>(singleCompletionAction.Invoke) }; } - if (continuationObject is List<object> continuationList) + if (continuationObject is List<object?> continuationList) { List<Delegate> result = new List<Delegate>(); - foreach (object obj in continuationList) + foreach (object? obj in continuationList) { var innerDelegates = GetDelegatesFromContinuationObject(obj); if (innerDelegates != null) @@ -6248,10 +6251,10 @@ namespace System.Threading.Tasks [DependencyReductionRoot] #endif //Do not remove: VS debugger calls this API directly using func-eval to populate data in the tasks window - private static Task GetActiveTaskFromId(int taskId) + private static Task? GetActiveTaskFromId(int taskId) { - Task task = null; - s_currentActiveTasks.TryGetValue(taskId, out task); + Task? task = null; + s_currentActiveTasks?.TryGetValue(taskId, out task); return task; } } @@ -6283,9 +6286,9 @@ namespace System.Threading.Tasks m_task = task; } - public object AsyncState { get { return m_task.AsyncState; } } + public object? AsyncState { get { return m_task.AsyncState; } } public TaskCreationOptions CreationOptions { get { return m_task.CreationOptions; } } - public Exception Exception { get { return m_task.Exception; } } + public Exception? Exception { get { return m_task.Exception; } } public int Id { get { return m_task.Id; } } public bool CancellationPending { get { return (m_task.Status == TaskStatus.WaitingToRun) && m_task.CancellationToken.IsCancellationRequested; } } public TaskStatus Status { get { return m_task.Status; } } @@ -6519,7 +6522,7 @@ namespace System.Threading.Tasks private readonly bool _lookForOce; public UnwrapPromise(Task outerTask, bool lookForOce) - : base((object)null, outerTask.CreationOptions & TaskCreationOptions.AttachedToParent) + : base((object?)null, outerTask.CreationOptions & TaskCreationOptions.AttachedToParent) { Debug.Assert(outerTask != null, "Expected non-null outerTask"); _lookForOce = lookForOce; @@ -6594,7 +6597,7 @@ namespace System.Threading.Tasks ThreadPool.UnsafeQueueUserWorkItem(state => { // InvokeCore(completingTask); - var tuple = (Tuple<UnwrapPromise<TResult>, Task>)state; + var tuple = (Tuple<UnwrapPromise<TResult>, Task>)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 tuple.Item1.InvokeCore(tuple.Item2); }, Tuple.Create<UnwrapPromise<TResult>, Task>(this, completingTask)); } @@ -6648,7 +6651,7 @@ namespace System.Threading.Tasks case TaskStatus.Faulted: var edis = task.GetExceptionDispatchInfos(); ExceptionDispatchInfo oceEdi; - OperationCanceledException oce; + OperationCanceledException? oce; if (lookForOce && edis.Count > 0 && (oceEdi = edis[0]) != null && (oce = oceEdi.SourceException as OperationCanceledException) != null) @@ -6670,7 +6673,7 @@ namespace System.Threading.Tasks if (Task.s_asyncDebuggingEnabled) RemoveFromActiveTasks(this); - result = TrySetResult(taskTResult != null ? taskTResult.Result : default); + result = TrySetResult(taskTResult != null ? taskTResult.Result : default!); // TODO-NULLABLE-GENERIC break; } return result; @@ -6681,7 +6684,7 @@ namespace System.Threading.Tasks /// transferring the appropriate results to ourself. /// </summary> /// <param name="task">The inner task returned by the task provided by the user.</param> - private void ProcessInnerTask(Task task) + private void ProcessInnerTask(Task? task) { // If the inner task is null, the proxy should be canceled. if (task == null) diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskCanceledException.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskCanceledException.cs index c3ee31a53c..5147f116eb 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskCanceledException.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskCanceledException.cs @@ -10,8 +10,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -using System; -using System.Runtime.InteropServices; +#nullable enable using System.Runtime.Serialization; namespace System.Threading.Tasks @@ -24,7 +23,7 @@ namespace System.Threading.Tasks public class TaskCanceledException : OperationCanceledException { [NonSerialized] - private readonly Task _canceledTask; // The task which has been canceled. + private readonly Task? _canceledTask; // The task which has been canceled. /// <summary> /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskCanceledException"/> class. @@ -38,7 +37,7 @@ namespace System.Threading.Tasks /// class with a specified error message. /// </summary> /// <param name="message">The error message that explains the reason for the exception.</param> - public TaskCanceledException(string message) : base(message) + public TaskCanceledException(string? message) : base(message) { } @@ -49,7 +48,7 @@ namespace System.Threading.Tasks /// </summary> /// <param name="message">The error message that explains the reason for the exception.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> - public TaskCanceledException(string message, Exception innerException) : base(message, innerException) + public TaskCanceledException(string? message, Exception? innerException) : base(message, innerException) { } @@ -61,7 +60,7 @@ namespace System.Threading.Tasks /// <param name="message">The error message that explains the reason for the exception.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> /// <param name="token">The <see cref="CancellationToken"/> that triggered the cancellation.</param> - public TaskCanceledException(string message, Exception innerException, CancellationToken token) : base(message, innerException, token) + public TaskCanceledException(string? message, Exception? innerException, CancellationToken token) : base(message, innerException, token) { } @@ -70,7 +69,7 @@ namespace System.Threading.Tasks /// with a reference to the <see cref="T:System.Threading.Tasks.Task"/> that has been canceled. /// </summary> /// <param name="task">A task that has been canceled.</param> - public TaskCanceledException(Task task) : + public TaskCanceledException(Task? task) : base(SR.TaskCanceledException_ctor_DefaultMessage, task != null ? task.CancellationToken : new CancellationToken()) { _canceledTask = task; @@ -94,6 +93,6 @@ namespace System.Threading.Tasks /// <see cref="T:System.Threading.Tasks.TaskCanceledException"/>, in which case /// this property will return null. /// </remarks> - public Task Task => _canceledTask; + public Task? Task => _canceledTask; } } diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskCompletionSource.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskCompletionSource.cs index c85a44f974..045486a6a1 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskCompletionSource.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskCompletionSource.cs @@ -11,6 +11,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System; using System.Diagnostics; using System.Collections.Generic; @@ -81,7 +82,7 @@ namespace System.Threading.Tasks /// </summary> /// <param name="state">The state to use as the underlying /// <see cref="T:System.Threading.Tasks.Task{TResult}"/>'s AsyncState.</param> - public TaskCompletionSource(object state) + public TaskCompletionSource(object? state) : this(state, TaskCreationOptions.None) { } @@ -98,7 +99,7 @@ namespace System.Threading.Tasks /// The <paramref name="creationOptions"/> represent options invalid for use /// with a <see cref="TaskCompletionSource{TResult}"/>. /// </exception> - public TaskCompletionSource(object state, TaskCreationOptions creationOptions) + public TaskCompletionSource(object? state, TaskCreationOptions creationOptions) { _task = new Task<TResult>(state, creationOptions); } @@ -150,7 +151,7 @@ namespace System.Threading.Tasks { if (exception == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception); - bool rval = _task.TrySetException(exception); + bool rval = _task.TrySetException(exception!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 if (!rval && !_task.IsCompleted) SpinUntilCompleted(); return rval; } @@ -180,11 +181,11 @@ namespace System.Threading.Tasks if (exceptions == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exceptions); List<Exception> defensiveCopy = new List<Exception>(); - foreach (Exception e in exceptions) + foreach (Exception e in exceptions!) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { if (e == null) ThrowHelper.ThrowArgumentException(ExceptionResource.TaskCompletionSourceT_TrySetException_NullException, ExceptionArgument.exceptions); - defensiveCopy.Add(e); + defensiveCopy.Add(e!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 } if (defensiveCopy.Count == 0) @@ -216,7 +217,7 @@ namespace System.Threading.Tasks { if (exception == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exception); - if (!TrySetException(exception)) + if (!TrySetException(exception!)) // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 { ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted); } diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskContinuation.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskContinuation.cs index 63ae2bd815..0968a747b1 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskContinuation.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskContinuation.cs @@ -2,9 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Security; +#nullable enable using System.Diagnostics; -using System.Runtime.ExceptionServices; using System.Runtime.CompilerServices; namespace System.Threading.Tasks @@ -12,13 +11,13 @@ namespace System.Threading.Tasks // Task type used to implement: Task ContinueWith(Action<Task,...>) internal sealed class ContinuationTaskFromTask : Task { - private Task m_antecedent; + private Task? m_antecedent; public ContinuationTaskFromTask( - Task antecedent, Delegate action, object state, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions) : + Task antecedent, Delegate action, object? state, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions) : base(action, state, Task.InternalCurrentIfAttached(creationOptions), default, creationOptions, internalOptions, null) { - Debug.Assert(action is Action<Task> || action is Action<Task, object>, + Debug.Assert(action is Action<Task> || action is Action<Task, object?>, "Invalid delegate type in ContinuationTaskFromTask"); m_antecedent = antecedent; } @@ -30,7 +29,7 @@ namespace System.Threading.Tasks { // Get and null out the antecedent. This is crucial to avoid a memory // leak with long chains of continuations. - var antecedent = m_antecedent; + Task? antecedent = m_antecedent; Debug.Assert(antecedent != null, "No antecedent was set for the ContinuationTaskFromTask."); m_antecedent = null; @@ -46,7 +45,7 @@ namespace System.Threading.Tasks return; } - if (m_action is Action<Task, object> actionWithState) + if (m_action is Action<Task, object?> actionWithState) { actionWithState(antecedent, m_stateObject); return; @@ -58,13 +57,13 @@ namespace System.Threading.Tasks // Task type used to implement: Task<TResult> ContinueWith(Func<Task,...>) internal sealed class ContinuationResultTaskFromTask<TResult> : Task<TResult> { - private Task m_antecedent; + private Task? m_antecedent; public ContinuationResultTaskFromTask( - Task antecedent, Delegate function, object state, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions) : + Task antecedent, Delegate function, object? state, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions) : base(function, state, Task.InternalCurrentIfAttached(creationOptions), default, creationOptions, internalOptions, null) { - Debug.Assert(function is Func<Task, TResult> || function is Func<Task, object, TResult>, + Debug.Assert(function is Func<Task, TResult> || function is Func<Task, object?, TResult>, "Invalid delegate type in ContinuationResultTaskFromTask"); m_antecedent = antecedent; } @@ -76,7 +75,7 @@ namespace System.Threading.Tasks { // Get and null out the antecedent. This is crucial to avoid a memory // leak with long chains of continuations. - var antecedent = m_antecedent; + Task? antecedent = m_antecedent; Debug.Assert(antecedent != null, "No antecedent was set for the ContinuationResultTaskFromTask."); m_antecedent = null; @@ -92,7 +91,7 @@ namespace System.Threading.Tasks return; } - if (m_action is Func<Task, object, TResult> funcWithState) + if (m_action is Func<Task, object?, TResult> funcWithState) { m_result = funcWithState(antecedent, m_stateObject); return; @@ -104,13 +103,13 @@ namespace System.Threading.Tasks // Task type used to implement: Task ContinueWith(Action<Task<TAntecedentResult>,...>) internal sealed class ContinuationTaskFromResultTask<TAntecedentResult> : Task { - private Task<TAntecedentResult> m_antecedent; + private Task<TAntecedentResult>? m_antecedent; public ContinuationTaskFromResultTask( - Task<TAntecedentResult> antecedent, Delegate action, object state, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions) : + Task<TAntecedentResult> antecedent, Delegate action, object? state, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions) : base(action, state, Task.InternalCurrentIfAttached(creationOptions), default, creationOptions, internalOptions, null) { - Debug.Assert(action is Action<Task<TAntecedentResult>> || action is Action<Task<TAntecedentResult>, object>, + Debug.Assert(action is Action<Task<TAntecedentResult>> || action is Action<Task<TAntecedentResult>, object?>, "Invalid delegate type in ContinuationTaskFromResultTask"); m_antecedent = antecedent; } @@ -122,7 +121,7 @@ namespace System.Threading.Tasks { // Get and null out the antecedent. This is crucial to avoid a memory // leak with long chains of continuations. - var antecedent = m_antecedent; + Task<TAntecedentResult>? antecedent = m_antecedent; Debug.Assert(antecedent != null, "No antecedent was set for the ContinuationTaskFromResultTask."); m_antecedent = null; @@ -138,7 +137,7 @@ namespace System.Threading.Tasks return; } - if (m_action is Action<Task<TAntecedentResult>, object> actionWithState) + if (m_action is Action<Task<TAntecedentResult>, object?> actionWithState) { actionWithState(antecedent, m_stateObject); return; @@ -150,13 +149,13 @@ namespace System.Threading.Tasks // Task type used to implement: Task<TResult> ContinueWith(Func<Task<TAntecedentResult>,...>) internal sealed class ContinuationResultTaskFromResultTask<TAntecedentResult, TResult> : Task<TResult> { - private Task<TAntecedentResult> m_antecedent; + private Task<TAntecedentResult>? m_antecedent; public ContinuationResultTaskFromResultTask( - Task<TAntecedentResult> antecedent, Delegate function, object state, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions) : + Task<TAntecedentResult> antecedent, Delegate function, object? state, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions) : base(function, state, Task.InternalCurrentIfAttached(creationOptions), default, creationOptions, internalOptions, null) { - Debug.Assert(function is Func<Task<TAntecedentResult>, TResult> || function is Func<Task<TAntecedentResult>, object, TResult>, + Debug.Assert(function is Func<Task<TAntecedentResult>, TResult> || function is Func<Task<TAntecedentResult>, object?, TResult>, "Invalid delegate type in ContinuationResultTaskFromResultTask"); m_antecedent = antecedent; } @@ -168,7 +167,7 @@ namespace System.Threading.Tasks { // Get and null out the antecedent. This is crucial to avoid a memory // leak with long chains of continuations. - var antecedent = m_antecedent; + Task<TAntecedentResult>? antecedent = m_antecedent; Debug.Assert(antecedent != null, "No antecedent was set for the ContinuationResultTaskFromResultTask."); m_antecedent = null; @@ -184,7 +183,7 @@ namespace System.Threading.Tasks return; } - if (m_action is Func<Task<TAntecedentResult>, object, TResult> funcWithState) + if (m_action is Func<Task<TAntecedentResult>, object?, TResult> funcWithState) { m_result = funcWithState(antecedent, m_stateObject); return; @@ -283,7 +282,7 @@ namespace System.Threading.Tasks m_options = options; m_taskScheduler = scheduler; if (AsyncCausalityTracer.LoggingOn) - AsyncCausalityTracer.TraceOperationCreation(m_task, "Task.ContinueWith: " + task.m_action.Method.Name); + AsyncCausalityTracer.TraceOperationCreation(m_task, "Task.ContinueWith: " + task.m_action!.Method.Name); if (Task.s_asyncDebuggingEnabled) Task.AddToActiveTasks(m_task); @@ -343,7 +342,7 @@ namespace System.Threading.Tasks else continuationTask.InternalCancel(false); } - internal override Delegate[] GetDelegateContinuationsForDebugger() + internal override Delegate[]? GetDelegateContinuationsForDebugger() { if (m_task.m_action == null) { @@ -358,9 +357,13 @@ namespace System.Threading.Tasks internal sealed class SynchronizationContextAwaitTaskContinuation : AwaitTaskContinuation { /// <summary>SendOrPostCallback delegate to invoke the action.</summary> - private static readonly SendOrPostCallback s_postCallback = state => ((Action)state)(); // can't use InvokeAction as it's SecurityCritical + private static readonly SendOrPostCallback s_postCallback = state => + { + Debug.Assert(state is Action); + ((Action)state)(); + }; /// <summary>Cached delegate for PostAction</summary> - private static ContextCallback s_postActionCallback; + private static ContextCallback? s_postActionCallback; /// <summary>The context with which to run the action.</summary> private readonly SynchronizationContext m_syncContext; @@ -403,8 +406,9 @@ namespace System.Threading.Tasks /// <summary>Calls InvokeOrPostAction(false) on the supplied SynchronizationContextAwaitTaskContinuation.</summary> /// <param name="state">The SynchronizationContextAwaitTaskContinuation.</param> - private static void PostAction(object state) + private static void PostAction(object? state) { + Debug.Assert(state is SynchronizationContextAwaitTaskContinuation); var c = (SynchronizationContextAwaitTaskContinuation)state; TplEventSource log = TplEventSource.Log; @@ -438,7 +442,7 @@ namespace System.Threading.Tasks [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ContextCallback GetPostActionCallback() { - ContextCallback callback = s_postActionCallback; + ContextCallback? callback = s_postActionCallback; if (callback == null) { s_postActionCallback = callback = PostAction; } // lazily initialize SecurityCritical delegate return callback; } @@ -489,7 +493,7 @@ namespace System.Threading.Tasks { try { - ((Action)state)(); + ((Action)state!)(); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } catch (Exception exception) { @@ -515,7 +519,7 @@ namespace System.Threading.Tasks internal class AwaitTaskContinuation : TaskContinuation, IThreadPoolWorkItem { /// <summary>The ExecutionContext with which to run the continuation.</summary> - private readonly ExecutionContext m_capturedContext; + private readonly ExecutionContext? m_capturedContext; /// <summary>The action to invoke.</summary> protected readonly Action m_action; @@ -539,7 +543,7 @@ namespace System.Threading.Tasks /// <param name="state">The state to pass to the action. Must not be null.</param> /// <param name="scheduler">The scheduler to target.</param> /// <returns>The created task.</returns> - protected Task CreateTask(Action<object> action, object state, TaskScheduler scheduler) + protected Task CreateTask(Action<object?> action, object? state, TaskScheduler scheduler) { Debug.Assert(action != null); Debug.Assert(scheduler != null); @@ -615,7 +619,7 @@ namespace System.Threading.Tasks void IThreadPoolWorkItem.Execute() { var log = TplEventSource.Log; - ExecutionContext context = m_capturedContext; + ExecutionContext? context = m_capturedContext; if (!log.IsEnabled() && context == null) { @@ -659,7 +663,11 @@ namespace System.Threading.Tasks } /// <summary>Cached delegate that invokes an Action passed as an object parameter.</summary> - private readonly static ContextCallback s_invokeContextCallback = (state) => ((Action)state)(); + private readonly static ContextCallback s_invokeContextCallback = (state) => + { + Debug.Assert(state is Action); + ((Action)state)(); + }; private readonly static Action<Action> s_invokeAction = (action) => action(); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -669,7 +677,7 @@ namespace System.Threading.Tasks /// <param name="callback">The callback to run.</param> /// <param name="state">The state to pass to the callback.</param> /// <param name="currentTask">A reference to Task.t_currentTask.</param> - protected void RunCallback(ContextCallback callback, object state, ref Task currentTask) + protected void RunCallback(ContextCallback callback, object? state, ref Task? currentTask) { Debug.Assert(callback != null); Debug.Assert(currentTask == Task.t_currentTask); @@ -681,7 +689,7 @@ namespace System.Threading.Tasks { if (prevCurrentTask != null) currentTask = null; - ExecutionContext context = m_capturedContext; + ExecutionContext? context = m_capturedContext; if (context == null) { // If there's no captured context, just run the callback directly. @@ -717,8 +725,8 @@ namespace System.Threading.Tasks /// </remarks> internal static void RunOrScheduleAction(Action action, bool allowInlining) { - ref Task currentTask = ref Task.t_currentTask; - Task prevCurrentTask = currentTask; + ref Task? currentTask = ref Task.t_currentTask; + Task? prevCurrentTask = currentTask; // If we're not allowed to run here, schedule the action if (!allowInlining || !IsValidLocationForInlining) @@ -753,8 +761,8 @@ namespace System.Threading.Tasks // Same logic as in the RunOrScheduleAction(Action, ...) overload, except invoking // box.Invoke instead of action(). - ref Task currentTask = ref Task.t_currentTask; - Task prevCurrentTask = currentTask; + ref Task? currentTask = ref Task.t_currentTask; + Task? prevCurrentTask = currentTask; // If we're not allowed to run here, schedule the action if (!allowInlining || !IsValidLocationForInlining) @@ -798,7 +806,7 @@ namespace System.Threading.Tasks /// <summary>Schedules the action to be executed. No ExecutionContext work is performed used.</summary> /// <param name="action">The action to invoke or queue.</param> /// <param name="task">The task scheduling the action.</param> - internal static void UnsafeScheduleAction(Action action, Task task) + internal static void UnsafeScheduleAction(Action action, Task? task) { AwaitTaskContinuation atc = new AwaitTaskContinuation(action, flowExecutionContext: false); diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskExceptionHolder.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskExceptionHolder.cs index 67b4220b8d..d35e6a2e67 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskExceptionHolder.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskExceptionHolder.cs @@ -10,6 +10,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; @@ -33,9 +34,9 @@ namespace System.Threading.Tasks /// The lazily-initialized list of faulting exceptions. Volatile /// so that it may be read to determine whether any exceptions were stored. /// </summary> - private volatile List<ExceptionDispatchInfo> m_faultExceptions; + private volatile List<ExceptionDispatchInfo>? m_faultExceptions; /// <summary>An exception that triggered the task to cancel.</summary> - private ExceptionDispatchInfo m_cancellationException; + private ExceptionDispatchInfo? m_cancellationException; /// <summary>Whether the holder was "observed" and thus doesn't cause finalization behavior.</summary> private volatile bool m_isHandled; @@ -252,7 +253,7 @@ namespace System.Threading.Tasks /// <param name="calledFromFinalizer">Whether this is being called from a finalizer.</param> /// <param name="includeThisException">An extra exception to be included (optionally).</param> /// <returns>The aggregate exception to throw.</returns> - internal AggregateException CreateExceptionObject(bool calledFromFinalizer, Exception includeThisException) + internal AggregateException CreateExceptionObject(bool calledFromFinalizer, Exception? includeThisException) { var exceptions = m_faultExceptions; Debug.Assert(exceptions != null, "Expected an initialized list."); @@ -284,7 +285,7 @@ namespace System.Threading.Tasks /// </summary> internal ReadOnlyCollection<ExceptionDispatchInfo> GetExceptionDispatchInfos() { - var exceptions = m_faultExceptions; + List<ExceptionDispatchInfo>? exceptions = m_faultExceptions; Debug.Assert(exceptions != null, "Expected an initialized list."); Debug.Assert(exceptions.Count > 0, "Expected at least one exception."); MarkAsHandled(false); @@ -298,7 +299,7 @@ namespace System.Threading.Tasks /// <returns> /// The ExceptionDispatchInfo for the cancellation exception. May be null. /// </returns> - internal ExceptionDispatchInfo GetCancellationExceptionDispatchInfo() + internal ExceptionDispatchInfo? GetCancellationExceptionDispatchInfo() { var edi = m_cancellationException; Debug.Assert(edi == null || edi.SourceException is OperationCanceledException, diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskExtensions.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskExtensions.cs index 75b4b0a378..4b45f75c98 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskExtensions.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskExtensions.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Runtime.CompilerServices; diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskFactory.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskFactory.cs index f7816d6206..cc5a5a1aa1 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskFactory.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskFactory.cs @@ -12,6 +12,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System; using System.Collections.Generic; using System.Security; @@ -40,18 +41,18 @@ namespace System.Threading.Tasks { // member variables private readonly CancellationToken m_defaultCancellationToken; - private readonly TaskScheduler m_defaultScheduler; + private readonly TaskScheduler? m_defaultScheduler; private readonly TaskCreationOptions m_defaultCreationOptions; private readonly TaskContinuationOptions m_defaultContinuationOptions; private TaskScheduler DefaultScheduler => m_defaultScheduler ?? TaskScheduler.Current; // sister method to above property -- avoids a TLS lookup - private TaskScheduler GetDefaultScheduler(Task currTask) + private TaskScheduler GetDefaultScheduler(Task? currTask) { return m_defaultScheduler ?? - (currTask != null && (currTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0 ? currTask.ExecutingTaskScheduler : + (currTask != null && (currTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0 ? currTask.ExecutingTaskScheduler! : // a "current" task must be executing, which means it must have a scheduler TaskScheduler.Default); } @@ -119,7 +120,7 @@ namespace System.Threading.Tasks /// initialized to the current scheduler (see <see /// cref="System.Threading.Tasks.TaskScheduler.Current">TaskScheduler.Current</see>). /// </remarks> - public TaskFactory(TaskScheduler scheduler) // null means to use TaskScheduler.Current + public TaskFactory(TaskScheduler? scheduler) // null means to use TaskScheduler.Current : this(default, TaskCreationOptions.None, TaskContinuationOptions.None, scheduler) { } @@ -190,7 +191,7 @@ namespace System.Threading.Tasks /// current scheduler (see <see /// cref="System.Threading.Tasks.TaskScheduler.Current">TaskScheduler.Current</see>). /// </remarks> - public TaskFactory(CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions, TaskScheduler scheduler) + public TaskFactory(CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions, TaskScheduler? scheduler) { CheckMultiTaskContinuationOptions(continuationOptions); CheckCreationOptions(creationOptions); @@ -239,7 +240,7 @@ namespace System.Threading.Tasks /// If null, <see cref="System.Threading.Tasks.TaskScheduler.Current">TaskScheduler.Current</see> /// will be used. /// </remarks> - public TaskScheduler Scheduler { get { return m_defaultScheduler; } } + public TaskScheduler? Scheduler { get { return m_defaultScheduler; } } /// <summary> /// Gets the <see cref="System.Threading.Tasks.TaskCreationOptions">TaskCreationOptions @@ -281,7 +282,7 @@ namespace System.Threading.Tasks /// </remarks> public Task StartNew(Action action) { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task.InternalStartNew(currTask, action, null, m_defaultCancellationToken, GetDefaultScheduler(currTask), m_defaultCreationOptions, InternalTaskOptions.None); } @@ -306,7 +307,7 @@ namespace System.Threading.Tasks /// </remarks> public Task StartNew(Action action, CancellationToken cancellationToken) { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task.InternalStartNew(currTask, action, null, cancellationToken, GetDefaultScheduler(currTask), m_defaultCreationOptions, InternalTaskOptions.None); } @@ -334,7 +335,7 @@ namespace System.Threading.Tasks /// </remarks> public Task StartNew(Action action, TaskCreationOptions creationOptions) { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task.InternalStartNew(currTask, action, null, m_defaultCancellationToken, GetDefaultScheduler(currTask), creationOptions, InternalTaskOptions.None); } @@ -396,9 +397,9 @@ namespace System.Threading.Tasks /// However, unless creation and scheduling must be separated, StartNew is the recommended approach /// for both simplicity and performance. /// </remarks> - public Task StartNew(Action<object> action, object state) + public Task StartNew(Action<object?> action, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task.InternalStartNew(currTask, action, state, m_defaultCancellationToken, GetDefaultScheduler(currTask), m_defaultCreationOptions, InternalTaskOptions.None); } @@ -425,9 +426,9 @@ namespace System.Threading.Tasks /// However, unless creation and scheduling must be separated, StartNew is the recommended approach /// for both simplicity and performance. /// </remarks> - public Task StartNew(Action<object> action, object state, CancellationToken cancellationToken) + public Task StartNew(Action<object?> action, object? state, CancellationToken cancellationToken) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task.InternalStartNew(currTask, action, state, cancellationToken, GetDefaultScheduler(currTask), m_defaultCreationOptions, InternalTaskOptions.None); } @@ -455,9 +456,9 @@ namespace System.Threading.Tasks /// However, unless creation and scheduling must be separated, StartNew is the recommended approach /// for both simplicity and performance. /// </remarks> - public Task StartNew(Action<object> action, object state, TaskCreationOptions creationOptions) + public Task StartNew(Action<object?> action, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task.InternalStartNew(currTask, action, state, m_defaultCancellationToken, GetDefaultScheduler(currTask), creationOptions, InternalTaskOptions.None); } @@ -496,7 +497,7 @@ namespace System.Threading.Tasks /// However, unless creation and scheduling must be separated, StartNew is the recommended approach /// for both simplicity and performance. /// </remarks> - public Task StartNew(Action<object> action, object state, CancellationToken cancellationToken, + public Task StartNew(Action<object?> action, object? state, CancellationToken cancellationToken, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 TaskCreationOptions creationOptions, TaskScheduler scheduler) { return Task.InternalStartNew( @@ -525,7 +526,7 @@ namespace System.Threading.Tasks /// </remarks> public Task<TResult> StartNew<TResult>(Func<TResult> function) { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task<TResult>.StartNew(currTask, function, m_defaultCancellationToken, m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask)); } @@ -556,7 +557,7 @@ namespace System.Threading.Tasks /// </remarks> public Task<TResult> StartNew<TResult>(Func<TResult> function, CancellationToken cancellationToken) { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task<TResult>.StartNew(currTask, function, cancellationToken, m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask)); } @@ -588,7 +589,7 @@ namespace System.Threading.Tasks /// </remarks> public Task<TResult> StartNew<TResult>(Func<TResult> function, TaskCreationOptions creationOptions) { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task<TResult>.StartNew(currTask, function, m_defaultCancellationToken, creationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask)); } @@ -657,9 +658,9 @@ namespace System.Threading.Tasks /// However, unless creation and scheduling must be separated, StartNew is the recommended approach /// for both simplicity and performance. /// </remarks> - public Task<TResult> StartNew<TResult>(Func<object, TResult> function, object state) + public Task<TResult> StartNew<TResult>(Func<object?, TResult> function, object? state) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task<TResult>.StartNew(currTask, function, state, m_defaultCancellationToken, m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask)); } @@ -690,9 +691,9 @@ namespace System.Threading.Tasks /// However, unless creation and scheduling must be separated, StartNew is the recommended approach /// for both simplicity and performance. /// </remarks> - public Task<TResult> StartNew<TResult>(Func<object, TResult> function, object state, CancellationToken cancellationToken) + public Task<TResult> StartNew<TResult>(Func<object?, TResult> function, object? state, CancellationToken cancellationToken) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task<TResult>.StartNew(currTask, function, state, cancellationToken, m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask)); } @@ -724,9 +725,9 @@ namespace System.Threading.Tasks /// However, unless creation and scheduling must be separated, StartNew is the recommended approach /// for both simplicity and performance. /// </remarks> - public Task<TResult> StartNew<TResult>(Func<object, TResult> function, object state, TaskCreationOptions creationOptions) + public Task<TResult> StartNew<TResult>(Func<object?, TResult> function, object? state, TaskCreationOptions creationOptions) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { - Task currTask = Task.InternalCurrent; + Task? currTask = Task.InternalCurrent; return Task<TResult>.StartNew(currTask, function, state, m_defaultCancellationToken, creationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask)); } @@ -769,7 +770,7 @@ namespace System.Threading.Tasks /// However, unless creation and scheduling must be separated, StartNew is the recommended approach /// for both simplicity and performance. /// </remarks> - public Task<TResult> StartNew<TResult>(Func<object, TResult> function, object state, CancellationToken cancellationToken, + public Task<TResult> StartNew<TResult>(Func<object?, TResult> function, object? state, CancellationToken cancellationToken, // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 TaskCreationOptions creationOptions, TaskScheduler scheduler) { return Task<TResult>.StartNew( @@ -879,9 +880,9 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task FromAsync( - Func<AsyncCallback, object, IAsyncResult> beginMethod, + Func<AsyncCallback, object?, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod, - object state) + object? state) { return FromAsync(beginMethod, endMethod, state, m_defaultCreationOptions); } @@ -909,8 +910,8 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task FromAsync( - Func<AsyncCallback, object, IAsyncResult> beginMethod, - Action<IAsyncResult> endMethod, object state, TaskCreationOptions creationOptions) + Func<AsyncCallback, object?, IAsyncResult> beginMethod, + Action<IAsyncResult> endMethod, object? state, TaskCreationOptions creationOptions) { return TaskFactory<VoidTaskResult>.FromAsyncImpl(beginMethod, null, endMethod, state, creationOptions); } @@ -938,10 +939,10 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task FromAsync<TArg1>( - Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, + Func<TArg1, AsyncCallback, object?, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod, TArg1 arg1, - object state) + object? state) { return FromAsync(beginMethod, endMethod, arg1, state, m_defaultCreationOptions); } @@ -974,9 +975,9 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task FromAsync<TArg1>( - Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, + Func<TArg1, AsyncCallback, object?, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod, - TArg1 arg1, object state, TaskCreationOptions creationOptions) + TArg1 arg1, object? state, TaskCreationOptions creationOptions) { return TaskFactory<VoidTaskResult>.FromAsyncImpl(beginMethod, null, endMethod, arg1, state, creationOptions); } @@ -1008,9 +1009,9 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task FromAsync<TArg1, TArg2>( - Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod, + Func<TArg1, TArg2, AsyncCallback, object?, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod, - TArg1 arg1, TArg2 arg2, object state) + TArg1 arg1, TArg2 arg2, object? state) { return FromAsync(beginMethod, endMethod, arg1, arg2, state, m_defaultCreationOptions); } @@ -1047,9 +1048,9 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task FromAsync<TArg1, TArg2>( - Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod, + Func<TArg1, TArg2, AsyncCallback, object?, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod, - TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions) + TArg1 arg1, TArg2 arg2, object? state, TaskCreationOptions creationOptions) { return TaskFactory<VoidTaskResult>.FromAsyncImpl(beginMethod, null, endMethod, arg1, arg2, state, creationOptions); } @@ -1085,9 +1086,9 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task FromAsync<TArg1, TArg2, TArg3>( - Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, + Func<TArg1, TArg2, TArg3, AsyncCallback, object?, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod, - TArg1 arg1, TArg2 arg2, TArg3 arg3, object state) + TArg1 arg1, TArg2 arg2, TArg3 arg3, object? state) { return FromAsync(beginMethod, endMethod, arg1, arg2, arg3, state, m_defaultCreationOptions); } @@ -1128,9 +1129,9 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task FromAsync<TArg1, TArg2, TArg3>( - Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, + Func<TArg1, TArg2, TArg3, AsyncCallback, object?, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod, - TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions) + TArg1 arg1, TArg2 arg2, TArg3 arg3, object? state, TaskCreationOptions creationOptions) { return TaskFactory<VoidTaskResult>.FromAsyncImpl<TArg1, TArg2, TArg3>(beginMethod, null, endMethod, arg1, arg2, arg3, state, creationOptions); } @@ -1243,8 +1244,8 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync<TResult>( - Func<AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endMethod, object state) + Func<AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult> endMethod, object? state) { return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, state, m_defaultCreationOptions); } @@ -1275,8 +1276,8 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync<TResult>( - Func<AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endMethod, object state, TaskCreationOptions creationOptions) + Func<AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult> endMethod, object? state, TaskCreationOptions creationOptions) { return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, state, creationOptions); } @@ -1306,8 +1307,8 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync<TArg1, TResult>( - Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endMethod, TArg1 arg1, object state) + Func<TArg1, AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult> endMethod, TArg1 arg1, object? state) { return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, state, m_defaultCreationOptions); } @@ -1341,8 +1342,8 @@ namespace System.Threading.Tasks /// <remarks> /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> - public Task<TResult> FromAsync<TArg1, TResult>(Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endMethod, TArg1 arg1, object state, TaskCreationOptions creationOptions) + public Task<TResult> FromAsync<TArg1, TResult>(Func<TArg1, AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult> endMethod, TArg1 arg1, object? state, TaskCreationOptions creationOptions) { return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, state, creationOptions); } @@ -1375,8 +1376,8 @@ namespace System.Threading.Tasks /// <remarks> /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> - public Task<TResult> FromAsync<TArg1, TArg2, TResult>(Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, object state) + public Task<TResult> FromAsync<TArg1, TArg2, TResult>(Func<TArg1, TArg2, AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, object? state) { return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, state, m_defaultCreationOptions); } @@ -1415,8 +1416,8 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync<TArg1, TArg2, TResult>( - Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions) + Func<TArg1, TArg2, AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, object? state, TaskCreationOptions creationOptions) { return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, state, creationOptions); } @@ -1454,8 +1455,8 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult>( - Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object state) + Func<TArg1, TArg2, TArg3, AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object? state) { return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, arg3, state, m_defaultCreationOptions); } @@ -1498,8 +1499,8 @@ namespace System.Threading.Tasks /// This method throws any exceptions thrown by the <paramref name="beginMethod"/>. /// </remarks> public Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult>( - Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, - Func<IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions) + Func<TArg1, TArg2, TArg3, AsyncCallback, object?, IAsyncResult> beginMethod, + Func<IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object? state, TaskCreationOptions creationOptions) { return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, arg3, state, creationOptions); } @@ -2284,7 +2285,7 @@ namespace System.Threading.Tasks private const int CompletedFlag = 0b_01; private const int SyncBlockingFlag = 0b_10; - private IList<Task> _tasks; // must track this for cleanup + private IList<Task>? _tasks; // must track this for cleanup private int _stateFlags; public CompleteOnInvokePromise(IList<Task> tasks, bool isSyncBlocking) : base() @@ -2331,7 +2332,8 @@ namespace System.Threading.Tasks // This may also help to avoided unnecessary invocations of this whenComplete delegate. // Note that we may be attempting to remove a continuation from a task that hasn't had it // added yet; while there's overhead there, the operation won't hurt anything. - var tasks = _tasks; + IList<Task>? tasks = _tasks; + Debug.Assert(tasks != null, "Should not have been nulled out yet."); int numTasks = tasks.Count; for (int i = 0; i < numTasks; i++) { @@ -2411,8 +2413,8 @@ namespace System.Threading.Tasks internal static void CommonCWAnyLogicCleanup(Task<Task> continuation) { // Force cleanup of the promise (e.g. removing continuations from each - // constituent task), by completing the promise with any value. - ((CompleteOnInvokePromise)continuation).Invoke(null); + // constituent task), by completing the promise with any value (it's not observable). + ((CompleteOnInvokePromise)continuation).Invoke(null!); } /// <summary> diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs index 1d1a581b0b..d8940044da 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs @@ -10,6 +10,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -142,7 +143,7 @@ namespace System.Threading.Tasks /// <exception cref="T:System.NotSupportedException"> /// This scheduler is unable to generate a list of queued tasks at this time. /// </exception> - protected abstract IEnumerable<Task> GetScheduledTasks(); + protected abstract IEnumerable<Task>? GetScheduledTasks(); /// <summary> /// Indicates the maximum concurrency level this @@ -174,7 +175,7 @@ namespace System.Threading.Tasks // Do not inline unstarted tasks (i.e., task.ExecutingTaskScheduler == null). // Do not inline TaskCompletionSource-style (a.k.a. "promise") tasks. // No need to attempt inlining if the task body was already run (i.e. either TASK_STATE_DELEGATE_INVOKED or TASK_STATE_CANCELED bits set) - TaskScheduler ets = task.ExecutingTaskScheduler; + TaskScheduler? ets = task.ExecutingTaskScheduler; // Delegate cross-scheduler inlining requests to target scheduler if (ets != this && ets != null) return ets.TryRunInline(task, taskWasPreviouslyQueued); @@ -254,7 +255,7 @@ namespace System.Threading.Tasks // // The global container that keeps track of TaskScheduler instances for debugging purposes. - private static ConditionalWeakTable<TaskScheduler, object> s_activeTaskSchedulers; + private static ConditionalWeakTable<TaskScheduler, object?>? s_activeTaskSchedulers; // An AppDomain-wide default manager. private static readonly TaskScheduler s_defaultTaskScheduler = new ThreadPoolTaskScheduler(); @@ -292,13 +293,13 @@ namespace System.Threading.Tasks /// <summary>Adds this scheduler ot the active schedulers tracking collection for debugging purposes.</summary> private void AddToActiveTaskSchedulers() { - ConditionalWeakTable<TaskScheduler, object> activeTaskSchedulers = s_activeTaskSchedulers; + ConditionalWeakTable<TaskScheduler, object?>? activeTaskSchedulers = s_activeTaskSchedulers; if (activeTaskSchedulers == null) { - Interlocked.CompareExchange(ref s_activeTaskSchedulers, new ConditionalWeakTable<TaskScheduler, object>(), null); + Interlocked.CompareExchange(ref s_activeTaskSchedulers, new ConditionalWeakTable<TaskScheduler, object?>(), null); activeTaskSchedulers = s_activeTaskSchedulers; } - activeTaskSchedulers.Add(this, null); + activeTaskSchedulers!.Add(this, null); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } /// <summary> @@ -323,8 +324,7 @@ namespace System.Threading.Tasks { get { - TaskScheduler current = InternalCurrent; - return current ?? TaskScheduler.Default; + return InternalCurrent ?? Default; } } @@ -335,11 +335,11 @@ namespace System.Threading.Tasks /// <remarks> /// When not called from within a task, <see cref="InternalCurrent"/> will return null. /// </remarks> - internal static TaskScheduler InternalCurrent + internal static TaskScheduler? InternalCurrent { get { - Task currentTask = Task.InternalCurrent; + Task? currentTask = Task.InternalCurrent; return ((currentTask != null) && ((currentTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0) ) ? currentTask.ExecutingTaskScheduler : null; @@ -472,11 +472,11 @@ namespace System.Threading.Tasks /// <exception cref="T:System.NotSupportedException"> /// This scheduler is unable to generate a list of queued tasks at this time. /// </exception> - internal Task[] GetScheduledTasksForDebugger() + internal Task[]? GetScheduledTasksForDebugger() { // this can throw InvalidOperationException indicating that they are unable to provide the info // at the moment. We should let the debugger receive that exception so that it can indicate it in the UI - IEnumerable<Task> activeTasksSource = GetScheduledTasks(); + IEnumerable<Task>? activeTasksSource = GetScheduledTasks(); if (activeTasksSource == null) return null; @@ -553,7 +553,7 @@ namespace System.Threading.Tasks } // returns the scheduler's GetScheduledTasks - public IEnumerable<Task> ScheduledTasks + public IEnumerable<Task>? ScheduledTasks { get { return m_taskScheduler.GetScheduledTasks(); } } @@ -578,15 +578,9 @@ namespace System.Threading.Tasks /// <exception cref="T:System.InvalidOperationException">This constructor expects <see cref="T:System.Threading.SynchronizationContext.Current"/> to be set.</exception> internal SynchronizationContextTaskScheduler() { - SynchronizationContext synContext = SynchronizationContext.Current; - - // make sure we have a synccontext to work with - if (synContext == null) - { + m_synchronizationContext = SynchronizationContext.Current ?? + // make sure we have a synccontext to work with throw new InvalidOperationException(SR.TaskScheduler_FromCurrentSynchronizationContext_NoCurrent); - } - - m_synchronizationContext = synContext; } /// <summary> @@ -615,11 +609,12 @@ namespace System.Threading.Tasks return TryExecuteTask(task); } else + { return false; + } } - // not implemented - protected override IEnumerable<Task> GetScheduledTasks() + protected override IEnumerable<Task>? GetScheduledTasks() { return null; } @@ -640,7 +635,11 @@ namespace System.Threading.Tasks } // preallocated SendOrPostCallback delegate - private static readonly SendOrPostCallback s_postCallback = s => ((Task)s).ExecuteEntry(); // with double-execute check because SC could be buggy + private static readonly SendOrPostCallback s_postCallback = s => + { + Debug.Assert(s is Task); + ((Task)s).ExecuteEntry(); // with double-execute check because SC could be buggy + }; } /// <summary> @@ -655,7 +654,7 @@ namespace System.Threading.Tasks /// </remarks> public class UnobservedTaskExceptionEventArgs : EventArgs { - private AggregateException m_exception; + private AggregateException? m_exception; internal bool m_observed = false; /// <summary> @@ -663,7 +662,7 @@ namespace System.Threading.Tasks /// with the unobserved exception. /// </summary> /// <param name="exception">The Exception that has gone unobserved.</param> - public UnobservedTaskExceptionEventArgs(AggregateException exception) { m_exception = exception; } + public UnobservedTaskExceptionEventArgs(AggregateException? exception) { m_exception = exception; } /// <summary> /// Marks the <see cref="Exception"/> as "observed," thus preventing it @@ -679,6 +678,6 @@ namespace System.Threading.Tasks /// <summary> /// The Exception that went unobserved. /// </summary> - public AggregateException Exception { get { return m_exception; } } + public AggregateException? Exception { get { return m_exception; } } } } diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskSchedulerException.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskSchedulerException.cs index 85ec497219..c68469c5cd 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskSchedulerException.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskSchedulerException.cs @@ -10,8 +10,7 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -using System; -using System.Runtime.InteropServices; +#nullable enable using System.Runtime.Serialization; namespace System.Threading.Tasks @@ -36,7 +35,7 @@ namespace System.Threading.Tasks /// class with a specified error message. /// </summary> /// <param name="message">The error message that explains the reason for the exception.</param> - public TaskSchedulerException(string message) : base(message) + public TaskSchedulerException(string? message) : base(message) { } @@ -46,7 +45,7 @@ namespace System.Threading.Tasks /// this exception. /// </summary> /// <param name="innerException">The exception that is the cause of the current exception.</param> - public TaskSchedulerException(Exception innerException) + public TaskSchedulerException(Exception? innerException) : base(SR.TaskSchedulerException_ctor_DefaultMessage, innerException) { } @@ -58,7 +57,7 @@ namespace System.Threading.Tasks /// </summary> /// <param name="message">The error message that explains the reason for the exception.</param> /// <param name="innerException">The exception that is the cause of the current exception.</param> - public TaskSchedulerException(string message, Exception innerException) : base(message, innerException) + public TaskSchedulerException(string? message, Exception? innerException) : base(message, innerException) { } diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskToApm.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskToApm.cs index add41f588e..110520a32b 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskToApm.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskToApm.cs @@ -16,6 +16,7 @@ // return TaskToApm.End<int>(asyncResult); // } +#nullable enable using System.Diagnostics; namespace System.Threading.Tasks @@ -33,7 +34,7 @@ namespace System.Threading.Tasks /// <param name="callback">The callback to be invoked upon completion.</param> /// <param name="state">The state to be stored in the IAsyncResult.</param> /// <returns>An IAsyncResult to represent the task's asynchronous operation.</returns> - public static IAsyncResult Begin(Task task, AsyncCallback callback, object state) + public static IAsyncResult Begin(Task task, AsyncCallback callback, object? state) { Debug.Assert(task != null); @@ -63,7 +64,7 @@ namespace System.Threading.Tasks /// <param name="asyncResult">The IAsyncResult to unwrap.</param> public static void End(IAsyncResult asyncResult) { - Task task; + Task? task; // If the IAsyncResult is our task-wrapping IAsyncResult, extract the Task. var twar = asyncResult as TaskWrapperAsyncResult; @@ -91,7 +92,7 @@ namespace System.Threading.Tasks /// <param name="asyncResult">The IAsyncResult to unwrap.</param> public static TResult End<TResult>(IAsyncResult asyncResult) { - Task<TResult> task; + Task<TResult>? task; // If the IAsyncResult is our task-wrapping IAsyncResult, extract the Task. var twar = asyncResult as TaskWrapperAsyncResult; @@ -158,7 +159,7 @@ namespace System.Threading.Tasks /// <summary>The wrapped Task.</summary> internal readonly Task Task; /// <summary>The new AsyncState value.</summary> - private readonly object _state; + private readonly object? _state; /// <summary>The new CompletedSynchronously value.</summary> private readonly bool _completedSynchronously; @@ -166,7 +167,7 @@ namespace System.Threading.Tasks /// <param name="task">The Task to wrap.</param> /// <param name="state">The new AsyncState value</param> /// <param name="completedSynchronously">The new CompletedSynchronously value.</param> - internal TaskWrapperAsyncResult(Task task, object state, bool completedSynchronously) + internal TaskWrapperAsyncResult(Task task, object? state, bool completedSynchronously) { Debug.Assert(task != null); Debug.Assert(!completedSynchronously || task.IsCompleted, "If completedSynchronously is true, the task must be completed."); @@ -180,7 +181,7 @@ namespace System.Threading.Tasks // - IsCompleted and AsyncWaitHandle just pass through to the Task. // - AsyncState and CompletedSynchronously return the corresponding values stored in this object. - object IAsyncResult.AsyncState { get { return _state; } } + object? IAsyncResult.AsyncState { get { return _state; } } bool IAsyncResult.CompletedSynchronously { get { return _completedSynchronously; } } bool IAsyncResult.IsCompleted { get { return this.Task.IsCompleted; } } WaitHandle IAsyncResult.AsyncWaitHandle { get { return ((IAsyncResult)this.Task).AsyncWaitHandle; } } diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ThreadPoolTaskScheduler.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ThreadPoolTaskScheduler.cs index 9ab28ef34a..05cb75bcbc 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ThreadPoolTaskScheduler.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ThreadPoolTaskScheduler.cs @@ -11,11 +11,9 @@ // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -using System; -using System.Security; -using System.Diagnostics; +#nullable enable using System.Collections.Generic; -using System.Text; +using System.Diagnostics; namespace System.Threading.Tasks { @@ -33,7 +31,11 @@ namespace System.Threading.Tasks } // static delegate for threads allocated to handle LongRunning tasks. - private static readonly ParameterizedThreadStart s_longRunningThreadWork = s => ((Task)s).ExecuteEntryUnsafe(threadPoolThread: null); + private static readonly ParameterizedThreadStart s_longRunningThreadWork = s => + { + Debug.Assert(s is Task); + ((Task)s).ExecuteEntryUnsafe(threadPoolThread: null); + }; /// <summary> /// Schedules a task to the ThreadPool. diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TplEventSource.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TplEventSource.cs index 94f0ec37e8..184cc32890 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TplEventSource.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TplEventSource.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Diagnostics.Tracing; using Internal.Runtime.CompilerServices; diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs index e9285ce45f..1b175614e2 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -63,7 +64,7 @@ namespace System.Threading.Tasks internal static Task CompletedTask => Task.CompletedTask; /// <summary>null if representing a successful synchronous completion, otherwise a <see cref="Task"/> or a <see cref="IValueTaskSource"/>.</summary> - internal readonly object _obj; + internal readonly object? _obj; /// <summary>Opaque value passed through to the <see cref="IValueTaskSource"/>.</summary> internal readonly short _token; /// <summary>true to continue on the capture context; otherwise, true.</summary> @@ -106,7 +107,7 @@ namespace System.Threading.Tasks } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private ValueTask(object obj, short token, bool continueOnCapturedContext) + private ValueTask(object? obj, short token, bool continueOnCapturedContext) { _obj = obj; _token = token; @@ -117,7 +118,7 @@ namespace System.Threading.Tasks public override int GetHashCode() => _obj?.GetHashCode() ?? 0; /// <summary>Returns a value indicating whether this value is equal to a specified <see cref="object"/>.</summary> - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is ValueTask && Equals((ValueTask)obj); @@ -141,7 +142,7 @@ namespace System.Threading.Tasks /// </remarks> public Task AsTask() { - object obj = _obj; + object? obj = _obj; Debug.Assert(obj == null || obj is Task || obj is IValueTaskSource); return obj == null ? CompletedTask : @@ -200,7 +201,7 @@ namespace System.Threading.Tasks /// <summary>Type used to create a <see cref="Task"/> to represent a <see cref="IValueTaskSource"/>.</summary> private sealed class ValueTaskSourceAsTask : Task { - private static readonly Action<object> s_completionAction = state => + private static readonly Action<object?> s_completionAction = state => { if (!(state is ValueTaskSourceAsTask vtst) || !(vtst._source is IValueTaskSource source)) @@ -240,11 +241,11 @@ namespace System.Threading.Tasks }; /// <summary>The associated <see cref="IValueTaskSource"/>.</summary> - private IValueTaskSource _source; + private IValueTaskSource? _source; /// <summary>The token to pass through to operations on <see cref="_source"/></summary> private readonly short _token; - public ValueTaskSourceAsTask(IValueTaskSource source, short token) + internal ValueTaskSourceAsTask(IValueTaskSource source, short token) { _token = token; _source = source; @@ -258,7 +259,7 @@ namespace System.Threading.Tasks [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - object obj = _obj; + object? obj = _obj; Debug.Assert(obj == null || obj is Task || obj is IValueTaskSource); if (obj == null) @@ -281,7 +282,7 @@ namespace System.Threading.Tasks [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - object obj = _obj; + object? obj = _obj; Debug.Assert(obj == null || obj is Task || obj is IValueTaskSource); if (obj == null) @@ -303,7 +304,7 @@ namespace System.Threading.Tasks { get { - object obj = _obj; + object? obj = _obj; Debug.Assert(obj == null || obj is Task || obj is IValueTaskSource); if (obj == null) @@ -330,7 +331,7 @@ namespace System.Threading.Tasks { get { - object obj = _obj; + object? obj = _obj; Debug.Assert(obj == null || obj is Task || obj is IValueTaskSource); if (obj == null) @@ -352,7 +353,7 @@ namespace System.Threading.Tasks [StackTraceHidden] internal void ThrowIfCompletedUnsuccessfully() { - object obj = _obj; + object? obj = _obj; Debug.Assert(obj == null || obj is Task || obj is IValueTaskSource); if (obj != null) @@ -411,9 +412,9 @@ namespace System.Threading.Tasks public readonly struct ValueTask<TResult> : IEquatable<ValueTask<TResult>> { /// <summary>A task canceled using `new CancellationToken(true)`. Lazily created only when first needed.</summary> - private static Task<TResult> s_canceledTask; + private static Task<TResult>? s_canceledTask; /// <summary>null if <see cref="_result"/> has the result, otherwise a <see cref="Task{TResult}"/> or a <see cref="IValueTaskSource{TResult}"/>.</summary> - internal readonly object _obj; + internal readonly object? _obj; /// <summary>The result to be used if the operation completed successfully synchronously.</summary> internal readonly TResult _result; /// <summary>Opaque value passed through to the <see cref="IValueTaskSource{TResult}"/>.</summary> @@ -449,7 +450,7 @@ namespace System.Threading.Tasks _obj = task; - _result = default; + _result = default!; // TODO-NULLABLE-GENERIC _continueOnCapturedContext = true; _token = 0; } @@ -468,7 +469,7 @@ namespace System.Threading.Tasks _obj = source; _token = token; - _result = default; + _result = default!; // TODO-NULLABLE-GENERIC _continueOnCapturedContext = true; } @@ -478,7 +479,7 @@ namespace System.Threading.Tasks /// <param name="token">The token.</param> /// <param name="continueOnCapturedContext">true to continue on captured context; otherwise, false.</param> [MethodImpl(MethodImplOptions.AggressiveInlining)] - private ValueTask(object obj, TResult result, short token, bool continueOnCapturedContext) + private ValueTask(object? obj, TResult result, short token, bool continueOnCapturedContext) { _obj = obj; _result = result; @@ -494,7 +495,7 @@ namespace System.Threading.Tasks 0; /// <summary>Returns a value indicating whether this value is equal to a specified <see cref="object"/>.</summary> - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is ValueTask<TResult> && Equals((ValueTask<TResult>)obj); @@ -521,7 +522,7 @@ namespace System.Threading.Tasks /// </remarks> public Task<TResult> AsTask() { - object obj = _obj; + object? obj = _obj; Debug.Assert(obj == null || obj is Task<TResult> || obj is IValueTaskSource<TResult>); if (obj == null) @@ -572,11 +573,11 @@ namespace System.Threading.Tasks return task; } - Task<TResult> canceledTask = s_canceledTask; + Task<TResult>? canceledTask = s_canceledTask; if (canceledTask == null) { // Benign race condition to initialize cached task, as identity doesn't matter. - s_canceledTask = Task.FromCanceled<TResult>(new CancellationToken(true)); + s_canceledTask = canceledTask = Task.FromCanceled<TResult>(new CancellationToken(true)); } return canceledTask; } @@ -593,7 +594,7 @@ namespace System.Threading.Tasks /// <summary>Type used to create a <see cref="Task{TResult}"/> to represent a <see cref="IValueTaskSource{TResult}"/>.</summary> private sealed class ValueTaskSourceAsTask : Task<TResult> { - private static readonly Action<object> s_completionAction = state => + private static readonly Action<object?> s_completionAction = state => { if (!(state is ValueTaskSourceAsTask vtst) || !(vtst._source is IValueTaskSource<TResult> source)) @@ -632,7 +633,7 @@ namespace System.Threading.Tasks }; /// <summary>The associated <see cref="IValueTaskSource"/>.</summary> - private IValueTaskSource<TResult> _source; + private IValueTaskSource<TResult>? _source; /// <summary>The token to pass through to operations on <see cref="_source"/></summary> private readonly short _token; @@ -650,7 +651,7 @@ namespace System.Threading.Tasks [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - object obj = _obj; + object? obj = _obj; Debug.Assert(obj == null || obj is Task<TResult> || obj is IValueTaskSource<TResult>); if (obj == null) @@ -673,7 +674,7 @@ namespace System.Threading.Tasks [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - object obj = _obj; + object? obj = _obj; Debug.Assert(obj == null || obj is Task<TResult> || obj is IValueTaskSource<TResult>); if (obj == null) @@ -695,7 +696,7 @@ namespace System.Threading.Tasks { get { - object obj = _obj; + object? obj = _obj; Debug.Assert(obj == null || obj is Task<TResult> || obj is IValueTaskSource<TResult>); if (obj == null) @@ -722,7 +723,7 @@ namespace System.Threading.Tasks { get { - object obj = _obj; + object? obj = _obj; Debug.Assert(obj == null || obj is Task<TResult> || obj is IValueTaskSource<TResult>); if (obj == null) @@ -745,7 +746,7 @@ namespace System.Threading.Tasks [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - object obj = _obj; + object? obj = _obj; Debug.Assert(obj == null || obj is Task<TResult> || obj is IValueTaskSource<TResult>); if (obj == null) @@ -776,7 +777,7 @@ namespace System.Threading.Tasks new ConfiguredValueTaskAwaitable<TResult>(new ValueTask<TResult>(_obj, _result, _token, continueOnCapturedContext)); /// <summary>Gets a string-representation of this <see cref="ValueTask{TResult}"/>.</summary> - public override string ToString() + public override string? ToString() { if (IsCompletedSuccessfully) { diff --git a/src/System.Private.CoreLib/shared/System/Threading/Thread.Unix.cs b/src/System.Private.CoreLib/shared/System/Threading/Thread.Unix.cs index 902fcf2650..e3ee7133da 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Thread.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Thread.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.ConstrainedExecution; namespace System.Threading diff --git a/src/System.Private.CoreLib/shared/System/Threading/Thread.Windows.cs b/src/System.Private.CoreLib/shared/System/Threading/Thread.Windows.cs index 44e5f38a76..b0bae93da6 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Thread.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Thread.Windows.cs @@ -2,8 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Runtime.ConstrainedExecution; - +#nullable enable namespace System.Threading { public sealed partial class Thread diff --git a/src/System.Private.CoreLib/shared/System/Threading/Thread.cs b/src/System.Private.CoreLib/shared/System/Threading/Thread.cs index ef492b0f8b..3a64d0164a 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Thread.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Thread.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Diagnostics; using System.Globalization; @@ -15,10 +16,10 @@ namespace System.Threading #endif public sealed partial class Thread : CriticalFinalizerObject { - private static AsyncLocal<IPrincipal> s_asyncLocalPrincipal; + private static AsyncLocal<IPrincipal?>? s_asyncLocalPrincipal; [ThreadStatic] - private static Thread t_currentThread; + private static Thread? t_currentThread; public Thread(ThreadStart start) : this() @@ -93,7 +94,7 @@ namespace System.Threading SetCultureOnUnstartedThreadNoCheck(value, uiCulture); } - partial void ThreadNameChanged(string value); + partial void ThreadNameChanged(string? value); public CultureInfo CurrentCulture { @@ -131,7 +132,7 @@ namespace System.Threading } } - public static IPrincipal CurrentPrincipal + public static IPrincipal? CurrentPrincipal { get { @@ -149,17 +150,17 @@ namespace System.Threading { return; } - Interlocked.CompareExchange(ref s_asyncLocalPrincipal, new AsyncLocal<IPrincipal>(), null); + Interlocked.CompareExchange(ref s_asyncLocalPrincipal, new AsyncLocal<IPrincipal?>(), null); } - s_asyncLocalPrincipal.Value = value; + s_asyncLocalPrincipal!.Value = value; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } } public static Thread CurrentThread => t_currentThread ?? InitializeCurrentThread(); - public ExecutionContext ExecutionContext => ExecutionContext.Capture(); + public ExecutionContext? ExecutionContext => ExecutionContext.Capture(); - public string Name + public string? Name { get => _name; set @@ -183,7 +184,7 @@ namespace System.Threading throw new PlatformNotSupportedException(SR.PlatformNotSupported_ThreadAbort); } - public void Abort(object stateInfo) + public void Abort(object? stateInfo) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ThreadAbort); } @@ -216,8 +217,8 @@ namespace System.Threading public static LocalDataStoreSlot AllocateNamedDataSlot(string name) => LocalDataStore.AllocateNamedSlot(name); public static LocalDataStoreSlot GetNamedDataSlot(string name) => LocalDataStore.GetNamedSlot(name); public static void FreeNamedDataSlot(string name) => LocalDataStore.FreeNamedSlot(name); - public static object GetData(LocalDataStoreSlot slot) => LocalDataStore.GetData(slot); - public static void SetData(LocalDataStoreSlot slot, object data) => LocalDataStore.SetData(slot, data); + public static object? GetData(LocalDataStoreSlot slot) => LocalDataStore.GetData(slot); + public static void SetData(LocalDataStoreSlot slot, object? data) => LocalDataStore.SetData(slot, data); [Obsolete("The ApartmentState property has been deprecated. Use GetApartmentState, SetApartmentState or TrySetApartmentState instead.", false)] public ApartmentState ApartmentState @@ -282,7 +283,7 @@ namespace System.Threading public static int VolatileRead(ref int address) => Volatile.Read(ref address); public static long VolatileRead(ref long address) => Volatile.Read(ref address); public static IntPtr VolatileRead(ref IntPtr address) => Volatile.Read(ref address); - public static object VolatileRead(ref object address) => Volatile.Read(ref address); + public static object? VolatileRead(ref object? address) => Volatile.Read(ref address); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 [CLSCompliant(false)] public static sbyte VolatileRead(ref sbyte address) => Volatile.Read(ref address); public static float VolatileRead(ref float address) => Volatile.Read(ref address); @@ -300,7 +301,7 @@ namespace System.Threading public static void VolatileWrite(ref int address, int value) => Volatile.Write(ref address, value); public static void VolatileWrite(ref long address, long value) => Volatile.Write(ref address, value); public static void VolatileWrite(ref IntPtr address, IntPtr value) => Volatile.Write(ref address, value); - public static void VolatileWrite(ref object address, object value) => Volatile.Write(ref address, value); + public static void VolatileWrite(ref object? address, object? value) => Volatile.Write(ref address, value); [CLSCompliant(false)] public static void VolatileWrite(ref sbyte address, sbyte value) => Volatile.Write(ref address, value); public static void VolatileWrite(ref float address, float value) => Volatile.Write(ref address, value); @@ -318,7 +319,7 @@ namespace System.Threading /// </summary> private static class LocalDataStore { - private static Dictionary<string, LocalDataStoreSlot> s_nameToSlotMap; + private static Dictionary<string, LocalDataStoreSlot>? s_nameToSlotMap; public static LocalDataStoreSlot AllocateSlot() { @@ -327,7 +328,7 @@ namespace System.Threading private static Dictionary<string, LocalDataStoreSlot> EnsureNameToSlotMap() { - Dictionary<string, LocalDataStoreSlot> nameToSlotMap = s_nameToSlotMap; + Dictionary<string, LocalDataStoreSlot>? nameToSlotMap = s_nameToSlotMap; if (nameToSlotMap != null) { return nameToSlotMap; @@ -372,7 +373,7 @@ namespace System.Threading } } - private static ThreadLocal<object> GetThreadLocal(LocalDataStoreSlot slot) + private static ThreadLocal<object?> GetThreadLocal(LocalDataStoreSlot slot) { if (slot == null) { @@ -383,12 +384,12 @@ namespace System.Threading return slot.Data; } - public static object GetData(LocalDataStoreSlot slot) + public static object? GetData(LocalDataStoreSlot slot) { return GetThreadLocal(slot).Value; } - public static void SetData(LocalDataStoreSlot slot, object value) + public static void SetData(LocalDataStoreSlot slot, object? value) { GetThreadLocal(slot).Value = value; } diff --git a/src/System.Private.CoreLib/shared/System/Threading/ThreadAbortException.cs b/src/System.Private.CoreLib/shared/System/Threading/ThreadAbortException.cs index 360e84d256..aa4cb299a8 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ThreadAbortException.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ThreadAbortException.cs @@ -14,6 +14,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System.Threading @@ -27,7 +28,7 @@ namespace System.Threading HResult = HResults.COR_E_THREADABORTED; } - public object ExceptionState => null; + public object? ExceptionState => null; internal ThreadAbortException(SerializationInfo info, StreamingContext context) : base(info, context) diff --git a/src/System.Private.CoreLib/shared/System/Threading/ThreadInterruptedException.cs b/src/System.Private.CoreLib/shared/System/Threading/ThreadInterruptedException.cs index 0d0288da24..01ff40d838 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ThreadInterruptedException.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ThreadInterruptedException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Threading @@ -24,13 +25,13 @@ namespace System.Threading HResult = HResults.COR_E_THREADINTERRUPTED; } - public ThreadInterruptedException(string message) + public ThreadInterruptedException(string? message) : base(message) { HResult = HResults.COR_E_THREADINTERRUPTED; } - public ThreadInterruptedException(string message, Exception innerException) + public ThreadInterruptedException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_THREADINTERRUPTED; @@ -40,4 +41,4 @@ namespace System.Threading { } } -}
\ No newline at end of file +} diff --git a/src/System.Private.CoreLib/shared/System/Threading/ThreadLocal.cs b/src/System.Private.CoreLib/shared/System/Threading/ThreadLocal.cs index 9f4beae9cf..8c19903ab7 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ThreadLocal.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ThreadLocal.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections.Generic; using System.Diagnostics; @@ -27,7 +28,7 @@ namespace System.Threading public class ThreadLocal<T> : IDisposable { // a delegate that returns the created value, if null the created value will be default(T) - private Func<T> _valueFactory; + private Func<T>? _valueFactory; // ts_slotArray is a table of thread-local values for all ThreadLocal<T> instances // @@ -35,10 +36,10 @@ namespace System.Threading // The slot relevant to this particular ThreadLocal<T> instance is determined by the _idComplement instance field stored in // the ThreadLocal<T> instance. [ThreadStatic] - private static LinkedSlotVolatile[] ts_slotArray; + private static LinkedSlotVolatile[]? ts_slotArray; [ThreadStatic] - private static FinalizationHelper ts_finalizationHelper; + private static FinalizationHelper? ts_finalizationHelper; // Slot ID of this ThreadLocal<> instance. We store a bitwise complement of the ID (that is ~ID), which allows us to distinguish // between the case when ID is 0 and an incompletely initialized object, either due to a thread abort in the constructor, or @@ -51,11 +52,11 @@ namespace System.Threading private volatile bool _initialized; // IdManager assigns and reuses slot IDs. Additionally, the object is also used as a global lock. - private static IdManager s_idManager = new IdManager(); + private static readonly IdManager s_idManager = new IdManager(); // A linked list of all values associated with this ThreadLocal<T> instance. // We create a dummy head node. That allows us to remove any (non-dummy) node without having to locate the m_linkedSlot field. - private LinkedSlot _linkedSlot = new LinkedSlot(null); + private LinkedSlot? _linkedSlot = new LinkedSlot(null); // Whether the Values property is supported private bool _trackAllValues; @@ -117,7 +118,7 @@ namespace System.Threading Initialize(valueFactory, trackAllValues); } - private void Initialize(Func<T> valueFactory, bool trackAllValues) + private void Initialize(Func<T>? valueFactory, bool trackAllValues) { _valueFactory = valueFactory; _trackAllValues = trackAllValues; @@ -185,9 +186,10 @@ namespace System.Threading } _initialized = false; - for (LinkedSlot linkedSlot = _linkedSlot._next; linkedSlot != null; linkedSlot = linkedSlot._next) + Debug.Assert(_linkedSlot != null, "Should be non-null if not yet disposed"); + for (LinkedSlot? linkedSlot = _linkedSlot._next; linkedSlot != null; linkedSlot = linkedSlot._next) { - LinkedSlotVolatile[] slotArray = linkedSlot._slotArray; + LinkedSlotVolatile[]? slotArray = linkedSlot._slotArray; if (slotArray == null) { @@ -200,7 +202,7 @@ namespace System.Threading // And clear the references from the slot table to the linked slot and the value so that // both can get garbage collected. - slotArray[id].Value._value = default; + slotArray[id].Value!._value = default!; // TODO-NULLABLE-GENERIC slotArray[id].Value = null; } } @@ -225,9 +227,9 @@ namespace System.Threading /// Calling this method forces initialization for the current thread, as is the /// case with accessing <see cref="Value"/> directly. /// </remarks> - public override string ToString() + public override string? ToString() { - return Value.ToString(); + return Value!.ToString(); // Throws NullReferenceException as if caller called ToString on the value itself } /// <summary> @@ -251,8 +253,8 @@ namespace System.Threading { get { - LinkedSlotVolatile[] slotArray = ts_slotArray; - LinkedSlot slot; + LinkedSlotVolatile[]? slotArray = ts_slotArray; + LinkedSlot? slot; int id = ~_idComplement; // @@ -277,8 +279,8 @@ namespace System.Threading } set { - LinkedSlotVolatile[] slotArray = ts_slotArray; - LinkedSlot slot; + LinkedSlotVolatile[]? slotArray = ts_slotArray; + LinkedSlot? slot; int id = ~_idComplement; // Attempt to set the value using the fast path @@ -318,7 +320,7 @@ namespace System.Threading T value; if (_valueFactory == null) { - value = default; + value = default!; // TODO-NULLABLE-GENERIC } else { @@ -335,7 +337,7 @@ namespace System.Threading return value; } - private void SetValueSlow(T value, LinkedSlotVolatile[] slotArray) + private void SetValueSlow(T value, LinkedSlotVolatile[]? slotArray) { int id = ~_idComplement; @@ -356,7 +358,8 @@ namespace System.Threading // If the slot array is not big enough to hold this ID, increase the table size. if (id >= slotArray.Length) { - GrowTable(ref slotArray, id + 1); + GrowTable(ref slotArray!, id + 1); + Debug.Assert(ts_finalizationHelper != null, "Should have been initialized when this thread's slot array was created."); ts_finalizationHelper.SlotArray = slotArray; ts_slotArray = slotArray; } @@ -371,7 +374,7 @@ namespace System.Threading { // Volatile read of the LinkedSlotVolatile.Value property ensures that the m_initialized read // that follows will not be reordered before the read of slotArray[id]. - LinkedSlot slot = slotArray[id].Value; + LinkedSlot? slot = slotArray[id].Value; // It is important to verify that the ThreadLocal instance has not been disposed. The check must come // after capturing slotArray[id], but before assigning the value into the slot. This ensures that @@ -383,7 +386,7 @@ namespace System.Threading throw new ObjectDisposedException(SR.ThreadLocal_Disposed); } - slot._value = value; + slot!._value = value; } } @@ -405,7 +408,8 @@ namespace System.Threading throw new ObjectDisposedException(SR.ThreadLocal_Disposed); } - LinkedSlot firstRealNode = _linkedSlot._next; + Debug.Assert(_linkedSlot != null, "Should only be null if disposed"); + LinkedSlot? firstRealNode = _linkedSlot._next; // Insert linkedSlot between nodes m_linkedSlot and firstRealNode. // (_linkedSlot is the dummy head node that should always be in the front.) @@ -448,7 +452,7 @@ namespace System.Threading } /// <summary>Gets all of the threads' values in a list.</summary> - private List<T> GetValuesAsList() + private List<T>? GetValuesAsList() { List<T> valueList = new List<T>(); int id = ~_idComplement; @@ -458,7 +462,8 @@ namespace System.Threading } // Walk over the linked list of slots and gather the values associated with this ThreadLocal instance. - for (LinkedSlot linkedSlot = _linkedSlot._next; linkedSlot != null; linkedSlot = linkedSlot._next) + Debug.Assert(_linkedSlot != null, "Should only be null if the instance was disposed."); + for (LinkedSlot? linkedSlot = _linkedSlot._next; linkedSlot != null; linkedSlot = linkedSlot._next) { // We can safely read linkedSlot.Value. Even if this ThreadLocal has been disposed in the meantime, the LinkedSlot // objects will never be assigned to another ThreadLocal instance. @@ -474,7 +479,7 @@ namespace System.Threading get { int count = 0; - for (LinkedSlot linkedSlot = _linkedSlot._next; linkedSlot != null; linkedSlot = linkedSlot._next) + for (LinkedSlot? linkedSlot = _linkedSlot?._next; linkedSlot != null; linkedSlot = linkedSlot._next) { count++; } @@ -498,7 +503,7 @@ namespace System.Threading throw new ObjectDisposedException(SR.ThreadLocal_Disposed); } - LinkedSlotVolatile[] slotArray = ts_slotArray; + LinkedSlotVolatile[]? slotArray = ts_slotArray; return slotArray != null && id < slotArray.Length && slotArray[id].Value != null; } } @@ -510,18 +515,18 @@ namespace System.Threading { get { - LinkedSlotVolatile[] slotArray = ts_slotArray; + LinkedSlotVolatile[]? slotArray = ts_slotArray; int id = ~_idComplement; - LinkedSlot slot; + LinkedSlot? slot; if (slotArray == null || id >= slotArray.Length || (slot = slotArray[id].Value) == null || !_initialized) - return default; + return default!; // TODO-NULLABLE-GENERIC return slot._value; } } /// <summary>Gets the values of all threads that accessed the ThreadLocal<T>.</summary> - internal List<T> ValuesForDebugDisplay // same as Values property, but doesn't throw if disposed + internal List<T>? ValuesForDebugDisplay // same as Values property, but doesn't throw if disposed { get { return GetValuesAsList(); } } @@ -547,7 +552,7 @@ namespace System.Threading { for (int i = 0; i < table.Length; i++) { - LinkedSlot linkedSlot = table[i].Value; + LinkedSlot? linkedSlot = table[i].Value; if (linkedSlot != null && linkedSlot._slotArray != null) { linkedSlot._slotArray = newTable; @@ -613,7 +618,7 @@ namespace System.Threading /// </summary> private struct LinkedSlotVolatile { - internal volatile LinkedSlot Value; + internal volatile LinkedSlot? Value; } /// <summary> @@ -626,22 +631,22 @@ namespace System.Threading /// </summary> private sealed class LinkedSlot { - internal LinkedSlot(LinkedSlotVolatile[] slotArray) + internal LinkedSlot(LinkedSlotVolatile[]? slotArray) { _slotArray = slotArray; } // The next LinkedSlot for this ThreadLocal<> instance - internal volatile LinkedSlot _next; + internal volatile LinkedSlot? _next; // The previous LinkedSlot for this ThreadLocal<> instance - internal volatile LinkedSlot _previous; + internal volatile LinkedSlot? _previous; // The SlotArray that stores this LinkedSlot at SlotArray.Table[id]. - internal volatile LinkedSlotVolatile[] _slotArray; + internal volatile LinkedSlotVolatile[]? _slotArray; // The value for this slot. - internal T _value; + internal T _value = default!; // TODO-NULLABLE-GENERIC } /// <summary> @@ -722,7 +727,7 @@ namespace System.Threading for (int i = 0; i < slotArray.Length; i++) { - LinkedSlot linkedSlot = slotArray[i].Value; + LinkedSlot? linkedSlot = slotArray[i].Value; if (linkedSlot == null) { // This slot in the table is empty @@ -776,6 +781,6 @@ namespace System.Threading public T Value => _tlocal.ValueForDebugDisplay; /// <summary>Return all values for all threads that have accessed this instance.</summary> - public List<T> Values => _tlocal.ValuesForDebugDisplay; + public List<T>? Values => _tlocal.ValuesForDebugDisplay; } } diff --git a/src/System.Private.CoreLib/shared/System/Threading/ThreadPool.cs b/src/System.Private.CoreLib/shared/System/Threading/ThreadPool.cs index f0f0d9ca8d..4e6ff27e30 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ThreadPool.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ThreadPool.cs @@ -11,13 +11,13 @@ ** =============================================================================*/ +#nullable enable using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Tracing; using System.Runtime.CompilerServices; -using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Threading.Tasks; using Internal.Runtime.CompilerServices; @@ -117,7 +117,7 @@ namespace System.Threading internal sealed class WorkStealingQueue { private const int INITIAL_SIZE = 32; - internal volatile object[] m_array = new object[INITIAL_SIZE]; // SOS's ThreadPool command depends on this name + internal volatile object?[] m_array = new object[INITIAL_SIZE]; // SOS's ThreadPool command depends on this name private volatile int m_mask = INITIAL_SIZE - 1; #if DEBUG @@ -189,7 +189,7 @@ namespace System.Threading if (count >= m_mask) { // We're full; expand the queue by doubling its size. - var newArray = new object[m_array.Length << 1]; + var newArray = new object?[m_array.Length << 1]; for (int i = 0; i < m_array.Length; i++) newArray[i] = m_array[(i + head) & m_mask]; @@ -217,7 +217,7 @@ namespace System.Threading // Fast path: check the tail. If equal, we can skip the lock. if (m_array[(m_tailIndex - 1) & m_mask] == obj) { - object unused = LocalPop(); + object? unused = LocalPop(); Debug.Assert(unused == null || unused == obj); return unused != null; } @@ -268,10 +268,10 @@ namespace System.Threading return false; } - public object LocalPop() => m_headIndex < m_tailIndex ? LocalPopCore() : null; + public object? LocalPop() => m_headIndex < m_tailIndex ? LocalPopCore() : null; [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread safety")] - private object LocalPopCore() + private object? LocalPopCore() { while (true) { @@ -289,7 +289,7 @@ namespace System.Threading if (m_headIndex <= tail) { int idx = tail & m_mask; - object obj = Volatile.Read(ref m_array[idx]); + object? obj = Volatile.Read(ref m_array[idx]); // Check for nulls in the array. if (obj == null) continue; @@ -309,7 +309,7 @@ namespace System.Threading { // Element still available. Take it. int idx = tail & m_mask; - object obj = Volatile.Read(ref m_array[idx]); + object? obj = Volatile.Read(ref m_array[idx]); // Check for nulls in the array. if (obj == null) continue; @@ -335,7 +335,7 @@ namespace System.Threading public bool CanSteal => m_headIndex < m_tailIndex; - public object TrySteal(ref bool missedSteal) + public object? TrySteal(ref bool missedSteal) { while (true) { @@ -354,7 +354,7 @@ namespace System.Threading if (head < m_tailIndex) { int idx = head & m_mask; - object obj = Volatile.Read(ref m_array[idx]); + object? obj = Volatile.Read(ref m_array[idx]); // Check for nulls in the array. if (obj == null) continue; @@ -457,7 +457,7 @@ namespace System.Threading if (loggingEnabled) System.Diagnostics.Tracing.FrameworkEventSource.Log.ThreadPoolEnqueueWorkObject(callback); - ThreadPoolWorkQueueThreadLocals tl = null; + ThreadPoolWorkQueueThreadLocals? tl = null; if (!forceGlobal) tl = ThreadPoolWorkQueueThreadLocals.threadLocals; @@ -479,10 +479,10 @@ namespace System.Threading return tl != null && tl.workStealingQueue.LocalFindAndPop(callback); } - public object Dequeue(ThreadPoolWorkQueueThreadLocals tl, ref bool missedSteal) + public object? Dequeue(ThreadPoolWorkQueueThreadLocals tl, ref bool missedSteal) { WorkStealingQueue localWsq = tl.workStealingQueue; - object callback; + object? callback; if ((callback = localWsq.LocalPop()) == null && // first try the local queue !workItems.TryDequeue(out callback)) // then try the global queue @@ -546,7 +546,7 @@ namespace System.Threading // false later, but only if we're absolutely certain that the queue is empty. // bool needAnotherThread = true; - object outerWorkItem = null; + object? outerWorkItem = null; try { // @@ -568,7 +568,7 @@ namespace System.Threading { bool missedSteal = false; // Use operate on workItem local to try block so it can be enregistered - object workItem = outerWorkItem = workQueue.Dequeue(tl, ref missedSteal); + object? workItem = outerWorkItem = workQueue.Dequeue(tl, ref missedSteal); if (workItem == null) { @@ -715,7 +715,7 @@ namespace System.Threading { if (null != workQueue) { - object cb; + object? cb; while ((cb = workStealingQueue.LocalPop()) != null) { Debug.Assert(null != cb); @@ -739,9 +739,9 @@ namespace System.Threading } } - public delegate void WaitCallback(object state); + public delegate void WaitCallback(object? state); - public delegate void WaitOrTimerCallback(object state, bool timedOut); // signaled or timed out + public delegate void WaitOrTimerCallback(object? state, bool timedOut); // signaled or timed out internal abstract class QueueUserWorkItemCallbackBase : IThreadPoolWorkItem { @@ -770,19 +770,20 @@ namespace System.Threading internal sealed class QueueUserWorkItemCallback : QueueUserWorkItemCallbackBase { - private WaitCallback _callback; // SOS's ThreadPool command depends on this name - private readonly object _state; + private WaitCallback? _callback; // SOS's ThreadPool command depends on this name + private readonly object? _state; private readonly ExecutionContext _context; private static readonly Action<QueueUserWorkItemCallback> s_executionContextShim = quwi => { + Debug.Assert(quwi._callback != null); WaitCallback callback = quwi._callback; quwi._callback = null; callback(quwi._state); }; - internal QueueUserWorkItemCallback(WaitCallback callback, object state, ExecutionContext context) + internal QueueUserWorkItemCallback(WaitCallback callback, object? state, ExecutionContext context) { Debug.Assert(context != null); @@ -801,7 +802,7 @@ namespace System.Threading internal sealed class QueueUserWorkItemCallback<TState> : QueueUserWorkItemCallbackBase { - private Action<TState> _callback; // SOS's ThreadPool command depends on this name + private Action<TState>? _callback; // SOS's ThreadPool command depends on this name private readonly TState _state; private readonly ExecutionContext _context; @@ -818,6 +819,7 @@ namespace System.Threading { base.Execute(); + Debug.Assert(_callback != null); Action<TState> callback = _callback; _callback = null; @@ -827,10 +829,10 @@ namespace System.Threading internal sealed class QueueUserWorkItemCallbackDefaultContext : QueueUserWorkItemCallbackBase { - private WaitCallback _callback; // SOS's ThreadPool command depends on this name - private readonly object _state; + private WaitCallback? _callback; // SOS's ThreadPool command depends on this name + private readonly object? _state; - internal QueueUserWorkItemCallbackDefaultContext(WaitCallback callback, object state) + internal QueueUserWorkItemCallbackDefaultContext(WaitCallback callback, object? state) { Debug.Assert(callback != null); @@ -843,6 +845,7 @@ namespace System.Threading ExecutionContext.CheckThreadPoolAndContextsAreDefault(); base.Execute(); + Debug.Assert(_callback != null); WaitCallback callback = _callback; _callback = null; @@ -854,7 +857,7 @@ namespace System.Threading internal sealed class QueueUserWorkItemCallbackDefaultContext<TState> : QueueUserWorkItemCallbackBase { - private Action<TState> _callback; // SOS's ThreadPool command depends on this name + private Action<TState>? _callback; // SOS's ThreadPool command depends on this name private readonly TState _state; internal QueueUserWorkItemCallbackDefaultContext(Action<TState> callback, TState state) @@ -870,6 +873,7 @@ namespace System.Threading ExecutionContext.CheckThreadPoolAndContextsAreDefault(); base.Execute(); + Debug.Assert(_callback != null); Action<TState> callback = _callback; _callback = null; @@ -879,15 +883,15 @@ namespace System.Threading } } - internal class _ThreadPoolWaitOrTimerCallback + internal sealed class _ThreadPoolWaitOrTimerCallback { private WaitOrTimerCallback _waitOrTimerCallback; - private ExecutionContext _executionContext; - private object _state; + private ExecutionContext? _executionContext; + private object? _state; private static readonly ContextCallback _ccbt = new ContextCallback(WaitOrTimerCallback_Context_t); private static readonly ContextCallback _ccbf = new ContextCallback(WaitOrTimerCallback_Context_f); - internal _ThreadPoolWaitOrTimerCallback(WaitOrTimerCallback waitOrTimerCallback, object state, bool flowExecutionContext) + internal _ThreadPoolWaitOrTimerCallback(WaitOrTimerCallback waitOrTimerCallback, object? state, bool flowExecutionContext) { _waitOrTimerCallback = waitOrTimerCallback; _state = state; @@ -916,7 +920,7 @@ namespace System.Threading { Debug.Assert(helper != null, "Null state passed to PerformWaitOrTimerCallback!"); // call directly if it is an unsafe call OR EC flow is suppressed - ExecutionContext context = helper._executionContext; + ExecutionContext? context = helper._executionContext; if (context == null) { WaitOrTimerCallback callback = helper._waitOrTimerCallback; @@ -935,7 +939,7 @@ namespace System.Threading public static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, - object state, + object? state, uint millisecondsTimeOutInterval, bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC ) @@ -949,7 +953,7 @@ namespace System.Threading public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, - object state, + object? state, uint millisecondsTimeOutInterval, bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC ) @@ -962,7 +966,7 @@ namespace System.Threading public static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, - object state, + object? state, int millisecondsTimeOutInterval, bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC ) @@ -975,7 +979,7 @@ namespace System.Threading public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, - object state, + object? state, int millisecondsTimeOutInterval, bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC ) @@ -988,7 +992,7 @@ namespace System.Threading public static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, - object state, + object? state, long millisecondsTimeOutInterval, bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC ) @@ -1003,7 +1007,7 @@ namespace System.Threading public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, - object state, + object? state, long millisecondsTimeOutInterval, bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC ) @@ -1018,7 +1022,7 @@ namespace System.Threading public static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, - object state, + object? state, TimeSpan timeout, bool executeOnlyOnce ) @@ -1034,7 +1038,7 @@ namespace System.Threading public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, - object state, + object? state, TimeSpan timeout, bool executeOnlyOnce ) @@ -1050,7 +1054,7 @@ namespace System.Threading public static bool QueueUserWorkItem(WaitCallback callBack) => QueueUserWorkItem(callBack, null); - public static bool QueueUserWorkItem(WaitCallback callBack, object state) + public static bool QueueUserWorkItem(WaitCallback callBack, object? state) { if (callBack == null) { @@ -1059,11 +1063,11 @@ namespace System.Threading EnsureInitialized(); - ExecutionContext context = ExecutionContext.Capture(); + ExecutionContext? context = ExecutionContext.Capture(); object tpcallBack = (context == null || context.IsDefault) ? - new QueueUserWorkItemCallbackDefaultContext(callBack, state) : - (object)new QueueUserWorkItemCallback(callBack, state, context); + new QueueUserWorkItemCallbackDefaultContext(callBack!, state) : + (object)new QueueUserWorkItemCallback(callBack!, state, context); ThreadPoolGlobals.workQueue.Enqueue(tpcallBack, forceGlobal: true); @@ -1079,11 +1083,11 @@ namespace System.Threading EnsureInitialized(); - ExecutionContext context = ExecutionContext.Capture(); + ExecutionContext? context = ExecutionContext.Capture(); object tpcallBack = (context == null || context.IsDefault) ? - new QueueUserWorkItemCallbackDefaultContext<TState>(callBack, state) : - (object)new QueueUserWorkItemCallback<TState>(callBack, state, context); + new QueueUserWorkItemCallbackDefaultContext<TState>(callBack!, state) : + (object)new QueueUserWorkItemCallback<TState>(callBack!, state, context); ThreadPoolGlobals.workQueue.Enqueue(tpcallBack, forceGlobal: !preferLocal); @@ -1111,19 +1115,19 @@ namespace System.Threading ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.state); } - UnsafeQueueUserWorkItemInternal((object)state, preferLocal); + UnsafeQueueUserWorkItemInternal((object)state!, preferLocal); return true; } EnsureInitialized(); ThreadPoolGlobals.workQueue.Enqueue( - new QueueUserWorkItemCallbackDefaultContext<TState>(callBack, state), forceGlobal: !preferLocal); + new QueueUserWorkItemCallbackDefaultContext<TState>(callBack!, state), forceGlobal: !preferLocal); return true; } - public static bool UnsafeQueueUserWorkItem(WaitCallback callBack, object state) + public static bool UnsafeQueueUserWorkItem(WaitCallback callBack, object? state) { if (callBack == null) { @@ -1132,7 +1136,7 @@ namespace System.Threading EnsureInitialized(); - object tpcallBack = new QueueUserWorkItemCallbackDefaultContext(callBack, state); + object tpcallBack = new QueueUserWorkItemCallbackDefaultContext(callBack!, state); ThreadPoolGlobals.workQueue.Enqueue(tpcallBack, forceGlobal: true); @@ -1152,7 +1156,7 @@ namespace System.Threading ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.callBack); } - UnsafeQueueUserWorkItemInternal(callBack, preferLocal); + UnsafeQueueUserWorkItemInternal(callBack!, preferLocal); return true; } @@ -1188,10 +1192,10 @@ namespace System.Threading { if (wsq != null && wsq.m_array != null) { - object[] items = wsq.m_array; + object?[] items = wsq.m_array; for (int i = 0; i < items.Length; i++) { - object item = items[i]; + object? item = items[i]; if (item != null) { yield return item; @@ -1206,10 +1210,10 @@ namespace System.Threading ThreadPoolWorkQueue.WorkStealingQueue wsq = ThreadPoolWorkQueueThreadLocals.threadLocals.workStealingQueue; if (wsq != null && wsq.m_array != null) { - object[] items = wsq.m_array; + object?[] items = wsq.m_array; for (int i = 0; i < items.Length; i++) { - object item = items[i]; + object? item = items[i]; if (item != null) yield return item; } diff --git a/src/System.Private.CoreLib/shared/System/Threading/ThreadPriority.cs b/src/System.Private.CoreLib/shared/System/Threading/ThreadPriority.cs index 3b34bd5eac..9ef95a1042 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ThreadPriority.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ThreadPriority.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { public enum ThreadPriority diff --git a/src/System.Private.CoreLib/shared/System/Threading/ThreadStart.cs b/src/System.Private.CoreLib/shared/System/Threading/ThreadStart.cs index 5532539fc7..11310ac296 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ThreadStart.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ThreadStart.cs @@ -12,6 +12,7 @@ ** =============================================================================*/ +#nullable enable namespace System.Threading { public delegate void ThreadStart(); diff --git a/src/System.Private.CoreLib/shared/System/Threading/ThreadStartException.cs b/src/System.Private.CoreLib/shared/System/Threading/ThreadStartException.cs index 5172555418..b22396bccc 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ThreadStartException.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ThreadStartException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Threading diff --git a/src/System.Private.CoreLib/shared/System/Threading/ThreadState.cs b/src/System.Private.CoreLib/shared/System/Threading/ThreadState.cs index 4bf3b5184d..9d0f374e22 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ThreadState.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ThreadState.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { [Flags] diff --git a/src/System.Private.CoreLib/shared/System/Threading/ThreadStateException.cs b/src/System.Private.CoreLib/shared/System/Threading/ThreadStateException.cs index d9ba48dfc8..9e0f26e9f5 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ThreadStateException.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ThreadStateException.cs @@ -12,6 +12,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System.Threading @@ -26,13 +27,13 @@ namespace System.Threading HResult = HResults.COR_E_THREADSTATE; } - public ThreadStateException(string message) + public ThreadStateException(string? message) : base(message) { HResult = HResults.COR_E_THREADSTATE; } - public ThreadStateException(string message, Exception innerException) + public ThreadStateException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_THREADSTATE; diff --git a/src/System.Private.CoreLib/shared/System/Threading/Timeout.cs b/src/System.Private.CoreLib/shared/System/Threading/Timeout.cs index df1ea5f2bc..85151291f7 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Timeout.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Timeout.cs @@ -2,9 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Threading; -using System; - +#nullable enable namespace System.Threading { // A constant used by methods that take a timeout (Object.Wait, Thread.Sleep diff --git a/src/System.Private.CoreLib/shared/System/Threading/TimeoutHelper.cs b/src/System.Private.CoreLib/shared/System/Threading/TimeoutHelper.cs index dd3291281e..524fb2b52a 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/TimeoutHelper.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/TimeoutHelper.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; namespace System.Threading diff --git a/src/System.Private.CoreLib/shared/System/Threading/Timer.cs b/src/System.Private.CoreLib/shared/System/Threading/Timer.cs index 180bcb5447..66d01ac81a 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Timer.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Timer.cs @@ -2,13 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Diagnostics.Tracing; using System.Threading.Tasks; namespace System.Threading { - public delegate void TimerCallback(object state); + public delegate void TimerCallback(object? state); // TimerQueue maintains a list of active timers. We use a single native timer to schedule all managed timers // in the process. @@ -109,8 +110,8 @@ namespace System.Threading // process the long list if the current time is greater than _currentAbsoluteThreshold (or // if the short list is now empty and we need to process the long list to know when to next // invoke FireNextTimers). - private TimerQueueTimer _shortTimers; - private TimerQueueTimer _longTimers; + private TimerQueueTimer? _shortTimers; + private TimerQueueTimer? _longTimers; // The current threshold, an absolute time where any timers scheduled to go off at or // before this time must be queued to the short list. @@ -135,7 +136,7 @@ namespace System.Threading { // We fire the first timer on this thread; any other timers that need to be fired // are queued to the ThreadPool. - TimerQueueTimer timerToFireOnThisThread = null; + TimerQueueTimer? timerToFireOnThisThread = null; lock (this) { @@ -151,7 +152,7 @@ namespace System.Threading // of sweeping the long timers, move anything that'll fire within the next threshold // to the short list. It's functionally ok if more timers end up in the short list // than is truly necessary (but not the opposite). - TimerQueueTimer timer = _shortTimers; + TimerQueueTimer? timer = _shortTimers; for (int listNum = 0; listNum < 2; listNum++) // short == 0, long == 1 { while (timer != null) @@ -160,7 +161,7 @@ namespace System.Threading // Save off the next timer to examine, in case our examination of this timer results // in our deleting or moving it; we'll continue after with this saved next timer. - TimerQueueTimer next = timer._next; + TimerQueueTimer? next = timer._next; uint elapsed = (uint)(nowTicks - timer._startTicks); int remaining = (int)timer._dueTime - (int)elapsed; @@ -334,7 +335,7 @@ namespace System.Threading private void LinkTimer(TimerQueueTimer timer) { // Use timer._short to decide to which list to add. - ref TimerQueueTimer listHead = ref timer._short ? ref _shortTimers : ref _longTimers; + ref TimerQueueTimer? listHead = ref timer._short ? ref _shortTimers : ref _longTimers; timer._next = listHead; if (timer._next != null) { @@ -346,7 +347,7 @@ namespace System.Threading private void UnlinkTimer(TimerQueueTimer timer) { - TimerQueueTimer t = timer._next; + TimerQueueTimer? t = timer._next; if (t != null) { t._prev = timer._prev; @@ -402,8 +403,8 @@ namespace System.Threading // The first six fields are maintained by TimerQueue. // Links to the next and prev timers in the list. - internal TimerQueueTimer _next; - internal TimerQueueTimer _prev; + internal TimerQueueTimer? _next; + internal TimerQueueTimer? _prev; // true if on the short list; otherwise, false. internal bool _short; @@ -419,8 +420,8 @@ namespace System.Threading // Info about the user's callback private readonly TimerCallback _timerCallback; - private readonly object _state; - private readonly ExecutionContext _executionContext; + private readonly object? _state; + private readonly ExecutionContext? _executionContext; // When Timer.Dispose(WaitHandle) is used, we need to signal the wait handle only // after all pending callbacks are complete. We set _canceled to prevent any callbacks that @@ -430,10 +431,10 @@ namespace System.Threading // instead of with a provided WaitHandle. private int _callbacksRunning; private volatile bool _canceled; - private volatile object _notifyWhenNoCallbacksRunning; // may be either WaitHandle or Task<bool> + private volatile object? _notifyWhenNoCallbacksRunning; // may be either WaitHandle or Task<bool> - internal TimerQueueTimer(TimerCallback timerCallback, object state, uint dueTime, uint period, bool flowExecutionContext) + internal TimerQueueTimer(TimerCallback timerCallback, object? state, uint dueTime, uint period, bool flowExecutionContext) { _timerCallback = timerCallback; _state = state; @@ -529,7 +530,7 @@ namespace System.Threading { lock (_associatedTimerQueue) { - object notifyWhenNoCallbacksRunning = _notifyWhenNoCallbacksRunning; + object? notifyWhenNoCallbacksRunning = _notifyWhenNoCallbacksRunning; // Mark the timer as canceled if it's not already. if (_canceled) @@ -571,7 +572,7 @@ namespace System.Threading // there wasn't a previous CloseAsync call that did. if (notifyWhenNoCallbacksRunning == null) { - var t = new Task<bool>((object)null, TaskCreationOptions.RunContinuationsAsynchronously); + var t = new Task<bool>((object?)null, TaskCreationOptions.RunContinuationsAsynchronously); _notifyWhenNoCallbacksRunning = t; return new ValueTask(t); } @@ -613,12 +614,12 @@ namespace System.Threading internal void SignalNoCallbacksRunning() { - object toSignal = _notifyWhenNoCallbacksRunning; + object? toSignal = _notifyWhenNoCallbacksRunning; Debug.Assert(toSignal is WaitHandle || toSignal is Task<bool>); if (toSignal is WaitHandle wh) { - EventWaitHandle.Set(wh.SafeWaitHandle); + EventWaitHandle.Set(wh.SafeWaitHandle!); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/2384 } else { @@ -632,7 +633,7 @@ namespace System.Threading FrameworkEventSource.Log.ThreadTransferReceiveObj(this, 1, string.Empty); // Call directly if EC flow is suppressed - ExecutionContext context = _executionContext; + ExecutionContext? context = _executionContext; if (context == null) { _timerCallback(_state); @@ -652,7 +653,8 @@ namespace System.Threading private static readonly ContextCallback s_callCallbackInContext = state => { - TimerQueueTimer t = (TimerQueueTimer)state; + Debug.Assert(state is TimerQueueTimer); + var t = (TimerQueueTimer)state; t._timerCallback(t._state); }; } @@ -667,7 +669,7 @@ namespace System.Threading // unwittingly be changing the lifetime of those timers. internal sealed class TimerHolder { - internal TimerQueueTimer _timer; + internal readonly TimerQueueTimer _timer; public TimerHolder(TimerQueueTimer timer) { @@ -716,10 +718,10 @@ namespace System.Threading { private const uint MAX_SUPPORTED_TIMEOUT = (uint)0xfffffffe; - private TimerHolder _timer; + private TimerHolder _timer = null!; // initialized in helper called by ctors public Timer(TimerCallback callback, - object state, + object? state, int dueTime, int period) : this(callback, state, dueTime, period, flowExecutionContext: true) @@ -727,7 +729,7 @@ namespace System.Threading } internal Timer(TimerCallback callback, - object state, + object? state, int dueTime, int period, bool flowExecutionContext) @@ -741,7 +743,7 @@ namespace System.Threading } public Timer(TimerCallback callback, - object state, + object? state, TimeSpan dueTime, TimeSpan period) { @@ -762,7 +764,7 @@ namespace System.Threading [CLSCompliant(false)] public Timer(TimerCallback callback, - object state, + object? state, uint dueTime, uint period) { @@ -770,7 +772,7 @@ namespace System.Threading } public Timer(TimerCallback callback, - object state, + object? state, long dueTime, long period) { @@ -787,7 +789,7 @@ namespace System.Threading public Timer(TimerCallback callback) { - int dueTime = -1; // we want timer to be registered, but not activated. Requires caller to call + int dueTime = -1; // We want timer to be registered, but not activated. Requires caller to call int period = -1; // Change after a timer instance is created. This is to avoid the potential // for a timer to be fired before the returned value is assigned to the variable, // potentially causing the callback to reference a bogus value (if passing the timer to the callback). @@ -796,7 +798,7 @@ namespace System.Threading } private void TimerSetup(TimerCallback callback, - object state, + object? state, uint dueTime, uint period, bool flowExecutionContext = true) diff --git a/src/System.Private.CoreLib/shared/System/Threading/TimerQueue.Portable.cs b/src/System.Private.CoreLib/shared/System/Threading/TimerQueue.Portable.cs index c9469c0a05..808ccc958f 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/TimerQueue.Portable.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/TimerQueue.Portable.cs @@ -12,8 +12,8 @@ namespace System.Threading // internal partial class TimerQueue : IThreadPoolWorkItem { - private static List<TimerQueue> s_scheduledTimers; - private static List<TimerQueue> s_scheduledTimersToFire; + private static List<TimerQueue>? s_scheduledTimers; + private static List<TimerQueue>? s_scheduledTimersToFire; /// <summary> /// This event is used by the timer thread to wait for timer expiration. It is also diff --git a/src/System.Private.CoreLib/shared/System/Threading/TimerQueue.Unix.cs b/src/System.Private.CoreLib/shared/System/Threading/TimerQueue.Unix.cs index 7c45637c49..d89a8f6a26 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/TimerQueue.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/TimerQueue.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { internal partial class TimerQueue diff --git a/src/System.Private.CoreLib/shared/System/Threading/Volatile.cs b/src/System.Private.CoreLib/shared/System/Threading/Volatile.cs index 845d2d089a..4ace8f994f 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/Volatile.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/Volatile.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Internal.Runtime.CompilerServices; @@ -214,16 +215,16 @@ namespace System.Threading #endregion #region T - private struct VolatileObject { public volatile object Value; } + private struct VolatileObject { public volatile object? Value; } [Intrinsic] [NonVersionable] - public static T Read<T>(ref T location) where T : class => + public static T Read<T>(ref T location) where T : class? => Unsafe.As<T>(Unsafe.As<T, VolatileObject>(ref location).Value); [Intrinsic] [NonVersionable] - public static void Write<T>(ref T location, T value) where T : class => + public static void Write<T>(ref T location, T value) where T : class? => Unsafe.As<T, VolatileObject>(ref location).Value = value; #endregion } diff --git a/src/System.Private.CoreLib/shared/System/Threading/WaitHandle.cs b/src/System.Private.CoreLib/shared/System/Threading/WaitHandle.cs index 911c3773ed..b2aeae8639 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/WaitHandle.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/WaitHandle.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using Microsoft.Win32.SafeHandles; @@ -16,10 +17,10 @@ namespace System.Threading // IMPORTANT: // - Do not add or rearrange fields as the EE depends on this layout. - private SafeWaitHandle _waitHandle; + private SafeWaitHandle? _waitHandle; [ThreadStatic] - private static SafeWaitHandle[] t_safeWaitHandlesForRent; + private static SafeWaitHandle?[]? t_safeWaitHandlesForRent; private protected enum OpenExistingResult { @@ -78,7 +79,7 @@ namespace System.Threading } } - public SafeWaitHandle SafeWaitHandle + public SafeWaitHandle? SafeWaitHandle // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/2384 { get { @@ -137,12 +138,7 @@ namespace System.Threading // The field value is modifiable via the public <see cref="WaitHandle.SafeWaitHandle"/> property, save it locally // to ensure that one instance is used in all places in this method - SafeWaitHandle waitHandle = _waitHandle; - if (waitHandle == null) - { - // Throw ObjectDisposedException for backward compatibility even though it is not be representative of the issue - throw new ObjectDisposedException(null, SR.ObjectDisposed_Generic); - } + SafeWaitHandle waitHandle = _waitHandle ?? throw new ObjectDisposedException(null, SR.ObjectDisposed_Generic); bool success = false; try @@ -151,7 +147,7 @@ namespace System.Threading waitHandle.DangerousAddRef(ref success); - SynchronizationContext context = SynchronizationContext.Current; + SynchronizationContext? context = SynchronizationContext.Current; if (context != null && context.IsWaitNotificationRequired()) { waitResult = context.Wait(new[] { waitHandle.DangerousGetHandle() }, false, millisecondsTimeout); @@ -177,9 +173,9 @@ namespace System.Threading // Returns an array for storing SafeWaitHandles in WaitMultiple calls. The array // is reused for subsequent calls to reduce GC pressure. - private static SafeWaitHandle[] RentSafeWaitHandleArray(int capacity) + private static SafeWaitHandle?[] RentSafeWaitHandleArray(int capacity) { - SafeWaitHandle[] safeWaitHandles = t_safeWaitHandlesForRent; + SafeWaitHandle?[]? safeWaitHandles = t_safeWaitHandlesForRent; t_safeWaitHandlesForRent = null; @@ -195,7 +191,7 @@ namespace System.Threading return safeWaitHandles; } - private static void ReturnSafeWaitHandleArray(SafeWaitHandle[] safeWaitHandles) + private static void ReturnSafeWaitHandleArray(SafeWaitHandle?[]? safeWaitHandles) => t_safeWaitHandlesForRent = safeWaitHandles; /// <summary> @@ -205,7 +201,7 @@ namespace System.Threading /// </summary> private static void ObtainSafeWaitHandles( ReadOnlySpan<WaitHandle> waitHandles, - Span<SafeWaitHandle> safeWaitHandles, + Span<SafeWaitHandle?> safeWaitHandles, Span<IntPtr> unsafeWaitHandles) { Debug.Assert(waitHandles != null); @@ -213,7 +209,7 @@ namespace System.Threading Debug.Assert(waitHandles.Length <= MaxWaitHandles); bool lastSuccess = true; - SafeWaitHandle lastSafeWaitHandle = null; + SafeWaitHandle? lastSafeWaitHandle = null; try { for (int i = 0; i < waitHandles.Length; ++i) @@ -224,12 +220,9 @@ namespace System.Threading throw new ArgumentNullException("waitHandles[" + i + ']', SR.ArgumentNull_ArrayElement); } - SafeWaitHandle safeWaitHandle = waitHandle._waitHandle; - if (safeWaitHandle == null) - { - // Throw ObjectDisposedException for backward compatibility even though it is not be representative of the issue + SafeWaitHandle safeWaitHandle = waitHandle._waitHandle ?? + // Throw ObjectDisposedException for backward compatibility even though it is not representative of the issue throw new ObjectDisposedException(null, SR.ObjectDisposed_Generic); - } lastSafeWaitHandle = safeWaitHandle; lastSuccess = false; @@ -242,7 +235,7 @@ namespace System.Threading { for (int i = 0; i < waitHandles.Length; ++i) { - SafeWaitHandle safeWaitHandle = safeWaitHandles[i]; + SafeWaitHandle? safeWaitHandle = safeWaitHandles[i]; if (safeWaitHandle == null) { break; @@ -258,6 +251,7 @@ namespace System.Threading if (!lastSuccess) { + Debug.Assert(lastSafeWaitHandle != null); lastSafeWaitHandle.DangerousRelease(); } @@ -299,9 +293,9 @@ namespace System.Threading throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1); } - SynchronizationContext context = SynchronizationContext.Current; + SynchronizationContext? context = SynchronizationContext.Current; bool useWaitContext = context != null && context.IsWaitNotificationRequired(); - SafeWaitHandle[] safeWaitHandles = RentSafeWaitHandleArray(waitHandles.Length); + SafeWaitHandle?[]? safeWaitHandles = RentSafeWaitHandleArray(waitHandles.Length); try { @@ -311,7 +305,7 @@ namespace System.Threading { IntPtr[] unsafeWaitHandles = new IntPtr[waitHandles.Length]; ObtainSafeWaitHandles(waitHandles, safeWaitHandles, unsafeWaitHandles); - waitResult = context.Wait(unsafeWaitHandles, waitAll, millisecondsTimeout); + waitResult = context!.Wait(unsafeWaitHandles, waitAll, millisecondsTimeout); } else { @@ -341,7 +335,7 @@ namespace System.Threading { if (safeWaitHandles[i] != null) { - safeWaitHandles[i].DangerousRelease(); + safeWaitHandles[i]!.DangerousRelease(); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34644 safeWaitHandles[i] = null; } } @@ -367,8 +361,8 @@ namespace System.Threading // The field value is modifiable via the public <see cref="WaitHandle.SafeWaitHandle"/> property, save it locally // to ensure that one instance is used in all places in this method - SafeWaitHandle safeWaitHandleToSignal = toSignal._waitHandle; - SafeWaitHandle safeWaitHandleToWaitOn = toWaitOn._waitHandle; + SafeWaitHandle? safeWaitHandleToSignal = toSignal._waitHandle; + SafeWaitHandle? safeWaitHandleToWaitOn = toWaitOn._waitHandle; if (safeWaitHandleToSignal == null || safeWaitHandleToWaitOn == null) { // Throw ObjectDisposedException for backward compatibility even though it is not be representative of the issue diff --git a/src/System.Private.CoreLib/shared/System/Threading/WaitHandleCannotBeOpenedException.cs b/src/System.Private.CoreLib/shared/System/Threading/WaitHandleCannotBeOpenedException.cs index 60821542b5..f54e013413 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/WaitHandleCannotBeOpenedException.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/WaitHandleCannotBeOpenedException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System.Threading @@ -15,12 +16,12 @@ namespace System.Threading HResult = HResults.COR_E_WAITHANDLECANNOTBEOPENED; } - public WaitHandleCannotBeOpenedException(string message) : base(message) + public WaitHandleCannotBeOpenedException(string? message) : base(message) { HResult = HResults.COR_E_WAITHANDLECANNOTBEOPENED; } - public WaitHandleCannotBeOpenedException(string message, Exception innerException) : base(message, innerException) + public WaitHandleCannotBeOpenedException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_WAITHANDLECANNOTBEOPENED; } diff --git a/src/System.Private.CoreLib/shared/System/TimeZoneNotFoundException.cs b/src/System.Private.CoreLib/shared/System/TimeZoneNotFoundException.cs index 3dc1bb1d4c..c28edaa2a9 100644 --- a/src/System.Private.CoreLib/shared/System/TimeZoneNotFoundException.cs +++ b/src/System.Private.CoreLib/shared/System/TimeZoneNotFoundException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System @@ -14,12 +15,12 @@ namespace System { } - public TimeZoneNotFoundException(string message) + public TimeZoneNotFoundException(string? message) : base(message) { } - public TimeZoneNotFoundException(string message, Exception innerException) + public TimeZoneNotFoundException(string? message, Exception? innerException) : base(message, innerException) { } diff --git a/src/System.Private.CoreLib/shared/System/TimeoutException.cs b/src/System.Private.CoreLib/shared/System/TimeoutException.cs index 2480f4bc28..7bb41e34f6 100644 --- a/src/System.Private.CoreLib/shared/System/TimeoutException.cs +++ b/src/System.Private.CoreLib/shared/System/TimeoutException.cs @@ -11,6 +11,7 @@ ** =============================================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -25,13 +26,13 @@ namespace System HResult = HResults.COR_E_TIMEOUT; } - public TimeoutException(string message) + public TimeoutException(string? message) : base(message) { HResult = HResults.COR_E_TIMEOUT; } - public TimeoutException(string message, Exception innerException) + public TimeoutException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_TIMEOUT; diff --git a/src/System.Private.CoreLib/shared/System/TypeAccessException.cs b/src/System.Private.CoreLib/shared/System/TypeAccessException.cs index e12a8b08dd..3cbeb02c26 100644 --- a/src/System.Private.CoreLib/shared/System/TypeAccessException.cs +++ b/src/System.Private.CoreLib/shared/System/TypeAccessException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System @@ -18,13 +19,13 @@ namespace System HResult = HResults.COR_E_TYPEACCESS; } - public TypeAccessException(string message) + public TypeAccessException(string? message) : base(message) { HResult = HResults.COR_E_TYPEACCESS; } - public TypeAccessException(string message, Exception inner) + public TypeAccessException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_TYPEACCESS; diff --git a/src/System.Private.CoreLib/shared/System/TypeInitializationException.cs b/src/System.Private.CoreLib/shared/System/TypeInitializationException.cs index 2ef822ab2c..c3aeb61036 100644 --- a/src/System.Private.CoreLib/shared/System/TypeInitializationException.cs +++ b/src/System.Private.CoreLib/shared/System/TypeInitializationException.cs @@ -14,6 +14,7 @@ ** =============================================================================*/ +#nullable enable using System.Globalization; using System.Runtime.Serialization; @@ -23,7 +24,7 @@ namespace System [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public sealed class TypeInitializationException : SystemException { - private string _typeName; + private string? _typeName; // This exception is not creatable without specifying the // inner exception. @@ -34,19 +35,19 @@ namespace System } - public TypeInitializationException(string fullTypeName, Exception innerException) + public TypeInitializationException(string? fullTypeName, Exception? innerException) : this(fullTypeName, SR.Format(SR.TypeInitialization_Type, fullTypeName), innerException) { } // This is called from within the runtime. I believe this is necessary // for Interop only, though it's not particularly useful. - internal TypeInitializationException(string message) : base(message) + internal TypeInitializationException(string? message) : base(message) { HResult = HResults.COR_E_TYPEINITIALIZATION; } - internal TypeInitializationException(string fullTypeName, string message, Exception innerException) + internal TypeInitializationException(string? fullTypeName, string? message, Exception? innerException) : base(message, innerException) { _typeName = fullTypeName; @@ -65,16 +66,6 @@ namespace System info.AddValue("TypeName", TypeName, typeof(string)); } - public string TypeName - { - get - { - if (_typeName == null) - { - return string.Empty; - } - return _typeName; - } - } + public string TypeName => _typeName ?? string.Empty; } } diff --git a/src/System.Private.CoreLib/shared/System/TypeLoadException.cs b/src/System.Private.CoreLib/shared/System/TypeLoadException.cs index e884faa5ce..92afe347e2 100644 --- a/src/System.Private.CoreLib/shared/System/TypeLoadException.cs +++ b/src/System.Private.CoreLib/shared/System/TypeLoadException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System @@ -16,13 +17,13 @@ namespace System HResult = HResults.COR_E_TYPELOAD; } - public TypeLoadException(string message) + public TypeLoadException(string? message) : base(message) { HResult = HResults.COR_E_TYPELOAD; } - public TypeLoadException(string message, Exception inner) + public TypeLoadException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_TYPELOAD; @@ -33,7 +34,7 @@ namespace System get { SetMessageField(); - return _message; + return _message!; } } @@ -59,9 +60,9 @@ namespace System // If ClassName != null, GetMessage will construct on the fly using it // and ResourceId (mscorrc.dll). This allows customization of the // class name format depending on the language environment. - private string _className; - private string _assemblyName; - private readonly string _messageArg; + private string? _className; + private string? _assemblyName; + private readonly string? _messageArg; private readonly int _resourceId; } } diff --git a/src/System.Private.CoreLib/shared/System/TypeUnloadedException.cs b/src/System.Private.CoreLib/shared/System/TypeUnloadedException.cs index a01ef37a8b..cbdb816246 100644 --- a/src/System.Private.CoreLib/shared/System/TypeUnloadedException.cs +++ b/src/System.Private.CoreLib/shared/System/TypeUnloadedException.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; namespace System @@ -16,13 +17,13 @@ namespace System HResult = HResults.COR_E_TYPEUNLOADED; } - public TypeUnloadedException(string message) + public TypeUnloadedException(string? message) : base(message) { HResult = HResults.COR_E_TYPEUNLOADED; } - public TypeUnloadedException(string message, Exception innerException) + public TypeUnloadedException(string? message, Exception? innerException) : base(message, innerException) { HResult = HResults.COR_E_TYPEUNLOADED; diff --git a/src/System.Private.CoreLib/shared/System/UnauthorizedAccessException.cs b/src/System.Private.CoreLib/shared/System/UnauthorizedAccessException.cs index e384dfeb31..46d9446c35 100644 --- a/src/System.Private.CoreLib/shared/System/UnauthorizedAccessException.cs +++ b/src/System.Private.CoreLib/shared/System/UnauthorizedAccessException.cs @@ -13,6 +13,7 @@ ** ===========================================================*/ +#nullable enable using System.Runtime.Serialization; namespace System @@ -29,13 +30,13 @@ namespace System HResult = HResults.COR_E_UNAUTHORIZEDACCESS; } - public UnauthorizedAccessException(string message) + public UnauthorizedAccessException(string? message) : base(message) { HResult = HResults.COR_E_UNAUTHORIZEDACCESS; } - public UnauthorizedAccessException(string message, Exception inner) + public UnauthorizedAccessException(string? message, Exception? inner) : base(message, inner) { HResult = HResults.COR_E_UNAUTHORIZEDACCESS; diff --git a/src/System.Private.CoreLib/src/Internal/Console.cs b/src/System.Private.CoreLib/src/Internal/Console.cs index ecdd0569ac..5a5fa52e92 100644 --- a/src/System.Private.CoreLib/src/Internal/Console.cs +++ b/src/System.Private.CoreLib/src/Internal/Console.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Text; using Microsoft.Win32.SafeHandles; @@ -27,7 +28,7 @@ namespace Internal } } - public static void WriteLine(string s) => + public static void WriteLine(string? s) => Write(s + Environment.NewLine); public static void WriteLine() => diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ExceptionSupport.cs b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ExceptionSupport.cs index 1772105d1e..8d133a5f05 100644 --- a/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ExceptionSupport.cs +++ b/src/System.Private.CoreLib/src/Internal/Runtime/InteropServices/WindowsRuntime/ExceptionSupport.cs @@ -1,8 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // 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.CompilerServices; using System.Runtime.InteropServices.WindowsRuntime; namespace Internal.Runtime.InteropServices.WindowsRuntime @@ -13,7 +14,7 @@ namespace Internal.Runtime.InteropServices.WindowsRuntime /// Attach restricted error information to the exception if it may apply to that exception, returning /// back the input value /// </summary> - public static Exception AttachRestrictedErrorInfo(Exception e) + public static Exception? AttachRestrictedErrorInfo(Exception? e) { // If there is no exception, then the restricted error info doesn't apply to it if (e != null) @@ -71,7 +72,7 @@ namespace Internal.Runtime.InteropServices.WindowsRuntime /// for the application to be invoked to process the error. /// </summary> /// <returns>true if the error was reported, false if not (ie running on Win8)</returns> - public static bool ReportUnhandledError(Exception ex) + public static bool ReportUnhandledError(Exception? ex) { return WindowsRuntimeMarshal.ReportUnhandledError(ex); } diff --git a/src/System.Private.CoreLib/src/Interop/Windows/OleAut32/Interop.VariantClear.cs b/src/System.Private.CoreLib/src/Interop/Windows/OleAut32/Interop.VariantClear.cs index ae95fe550c..e2b9d3ce61 100644 --- a/src/System.Private.CoreLib/src/Interop/Windows/OleAut32/Interop.VariantClear.cs +++ b/src/System.Private.CoreLib/src/Interop/Windows/OleAut32/Interop.VariantClear.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/src/Microsoft/Win32/OAVariantLib.cs b/src/System.Private.CoreLib/src/Microsoft/Win32/OAVariantLib.cs index 99ac9ba6a3..047b8bc38f 100644 --- a/src/System.Private.CoreLib/src/Microsoft/Win32/OAVariantLib.cs +++ b/src/System.Private.CoreLib/src/Microsoft/Win32/OAVariantLib.cs @@ -13,6 +13,7 @@ ** ===========================================================*/ +#nullable enable namespace Microsoft.Win32 { using System; @@ -33,7 +34,7 @@ namespace Microsoft.Win32 public const int CalendarHijri = 0x08; public const int LocalBool = 0x10; - internal static readonly Type[] ClassTypes = { + internal static readonly Type?[] ClassTypes = { typeof(Empty), typeof(void), typeof(bool), diff --git a/src/System.Private.CoreLib/src/Microsoft/Win32/UnsafeNativeMethods.cs b/src/System.Private.CoreLib/src/Microsoft/Win32/UnsafeNativeMethods.cs index 8e0a68248b..2f69f63508 100644 --- a/src/System.Private.CoreLib/src/Microsoft/Win32/UnsafeNativeMethods.cs +++ b/src/System.Private.CoreLib/src/Microsoft/Win32/UnsafeNativeMethods.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace Microsoft.Win32 { using Microsoft.Win32.SafeHandles; diff --git a/src/System.Private.CoreLib/src/System/BadImageFormatException.CoreCLR.cs b/src/System.Private.CoreLib/src/System/BadImageFormatException.CoreCLR.cs index 094668bde0..4847fab043 100644 --- a/src/System.Private.CoreLib/src/System/BadImageFormatException.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/BadImageFormatException.CoreCLR.cs @@ -2,12 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System { public partial class BadImageFormatException { // Do not delete: this is invoked from native code. - private BadImageFormatException(string fileName, string fusionLog, int hResult) + private BadImageFormatException(string? fileName, string? fusionLog, int hResult) : base(null) { HResult = hResult; diff --git a/src/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs index f0e7d09f70..09ec41cf4e 100644 --- a/src/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Delegate.CoreCLR.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; @@ -15,11 +16,11 @@ namespace System public abstract partial class Delegate : ICloneable, ISerializable { // _target is the object we will invoke on - internal object _target; + internal object? _target; // Initialized by VM as needed; null if static delegate // MethodBase, either cached after first request or assigned from a DynamicMethod // For open delegates to collectible types, this may be a LoaderAllocator object - internal object _methodBase; + internal object? _methodBase; // Initialized by VM as needed // _methodPtr is a pointer to the method we will invoke // It could be a small thunk if this is a static or UM call @@ -53,7 +54,7 @@ namespace System throw new ArgumentException(SR.Arg_DlgtTargMeth); } - // This constructor is called from a class to generate a + // This constructor is called from a class to generate a // delegate based upon a static method name and the Type object // for the class defining the method. protected Delegate(Type target, string method) @@ -67,8 +68,7 @@ namespace System if (method == null) throw new ArgumentNullException(nameof(method)); - RuntimeType rtTarget = target as RuntimeType; - if (rtTarget == null) + if (!(target is RuntimeType rtTarget)) throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(target)); // This API existed in v1/v1.1 and only expected to create open @@ -84,7 +84,7 @@ namespace System DelegateBindingFlags.CaselessMatching); } - protected virtual object DynamicInvokeImpl(object[] args) + protected virtual object? DynamicInvokeImpl(object?[]? args) { RuntimeMethodHandleInternal method = new RuntimeMethodHandleInternal(GetInvokeMethod()); RuntimeMethodInfo invoke = (RuntimeMethodInfo)RuntimeType.GetMethodBase((RuntimeType)this.GetType(), method); @@ -93,7 +93,7 @@ namespace System } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == null || !InternalEqualTypes(this, obj)) return false; @@ -107,7 +107,7 @@ namespace System // even though the fields were not all equals the delegates may still match // When target carries the delegate itself the 2 targets (delegates) may be different instances // but the delegates are logically the same - // It may also happen that the method pointer was not jitted when creating one delegate and jitted in the other + // It may also happen that the method pointer was not jitted when creating one delegate and jitted in the other // if that's the case the delegates may still be equals but we need to make a more complicated check if (_methodPtrAux == IntPtr.Zero) @@ -136,7 +136,7 @@ namespace System } // method ptrs don't match, go down long path - // + // if (_methodBase == null || d._methodBase == null || !(_methodBase is MethodInfo) || !(d._methodBase is MethodInfo)) return Delegate.InternalEqualMethodHandles(this, d); else @@ -166,7 +166,7 @@ namespace System if ((_methodBase == null) || !(_methodBase is MethodInfo)) { IRuntimeMethodInfo method = FindMethodHandle(); - RuntimeType declaringType = RuntimeMethodHandle.GetDeclaringType(method); + RuntimeType? declaringType = RuntimeMethodHandle.GetDeclaringType(method); // need a proper declaring type instance method on a generic type if (RuntimeTypeHandle.IsGenericTypeDefinition(declaringType) || RuntimeTypeHandle.HasInstantiation(declaringType)) { @@ -185,7 +185,7 @@ namespace System // types at each step) until we find the declaring type. Since the declaring type // we get from the method is probably shared and those in the hierarchy we're // walking won't be we compare using the generic type definition forms instead. - Type currentType = _target.GetType(); + Type currentType = _target!.GetType(); Type targetType = declaringType.GetGenericTypeDefinition(); while (currentType != null) { @@ -216,7 +216,7 @@ namespace System return (MethodInfo)_methodBase; } - public object Target + public object? Target { get { @@ -225,7 +225,7 @@ namespace System } // V1 API. - public static Delegate CreateDelegate(Type type, object target, string method, bool ignoreCase, bool throwOnBindFailure) + public static Delegate? CreateDelegate(Type type, object target, string method, bool ignoreCase, bool throwOnBindFailure) { if (type == null) throw new ArgumentNullException(nameof(type)); @@ -234,8 +234,7 @@ namespace System if (method == null) throw new ArgumentNullException(nameof(method)); - RuntimeType rtType = type as RuntimeType; - if (rtType == null) + if (!(type is RuntimeType rtType)) throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type)); if (!rtType.IsDelegate()) throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type)); @@ -256,14 +255,15 @@ namespace System { if (throwOnBindFailure) throw new ArgumentException(SR.Arg_DlgtTargMeth); - d = null; + + return null; } return d; } // V1 API. - public static Delegate CreateDelegate(Type type, Type target, string method, bool ignoreCase, bool throwOnBindFailure) + public static Delegate? CreateDelegate(Type type, Type target, string method, bool ignoreCase, bool throwOnBindFailure) { if (type == null) throw new ArgumentNullException(nameof(type)); @@ -274,12 +274,11 @@ namespace System if (method == null) throw new ArgumentNullException(nameof(method)); - RuntimeType rtType = type as RuntimeType; - RuntimeType rtTarget = target as RuntimeType; - if (rtType == null) + if (!(type is RuntimeType rtType)) throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type)); - if (rtTarget == null) + if (!(target is RuntimeType rtTarget)) throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(target)); + if (!rtType.IsDelegate()) throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type)); @@ -295,14 +294,15 @@ namespace System { if (throwOnBindFailure) throw new ArgumentException(SR.Arg_DlgtTargMeth); - d = null; + + return null; } return d; } // V1 API. - public static Delegate CreateDelegate(Type type, MethodInfo method, bool throwOnBindFailure) + public static Delegate? CreateDelegate(Type type, MethodInfo method, bool throwOnBindFailure) { // Validate the parameters. if (type == null) @@ -310,12 +310,10 @@ namespace System if (method == null) throw new ArgumentNullException(nameof(method)); - RuntimeType rtType = type as RuntimeType; - if (rtType == null) + if (!(type is RuntimeType rtType)) throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type)); - RuntimeMethodInfo rmi = method as RuntimeMethodInfo; - if (rmi == null) + if (!(method is RuntimeMethodInfo rmi)) throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(method)); if (!rtType.IsDelegate()) @@ -329,7 +327,7 @@ namespace System // pass us a static method or a method with a non-exact signature // and the only change in behavior from v1.1 there is that we won't // fail the call). - Delegate d = CreateDelegateInternal( + Delegate? d = CreateDelegateInternal( rtType, rmi, null, @@ -342,7 +340,7 @@ namespace System } // V2 API. - public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure) + public static Delegate? CreateDelegate(Type type, object? firstArgument, MethodInfo method, bool throwOnBindFailure) { // Validate the parameters. if (type == null) @@ -350,12 +348,10 @@ namespace System if (method == null) throw new ArgumentNullException(nameof(method)); - RuntimeType rtType = type as RuntimeType; - if (rtType == null) + if (!(type is RuntimeType rtType)) throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type)); - RuntimeMethodInfo rmi = method as RuntimeMethodInfo; - if (rmi == null) + if (!(method is RuntimeMethodInfo rmi)) throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(method)); if (!rtType.IsDelegate()) @@ -366,7 +362,7 @@ namespace System // instance methods with relaxed signature checking. The delegate // can also be closed over null. There's no ambiguity with all these // options since the caller is providing us a specific MethodInfo. - Delegate d = CreateDelegateInternal( + Delegate? d = CreateDelegateInternal( rtType, rmi, firstArgument, @@ -383,8 +379,7 @@ namespace System // // V2 internal API. - // This is Critical because it skips the security check when creating the delegate. - internal static Delegate CreateDelegateNoSecurityCheck(Type type, object target, RuntimeMethodHandle method) + internal static Delegate CreateDelegateNoSecurityCheck(Type type, object? target, RuntimeMethodHandle method) { // Validate the parameters. if (type == null) @@ -393,8 +388,7 @@ namespace System if (method.IsNullHandle()) throw new ArgumentNullException(nameof(method)); - RuntimeType rtType = type as RuntimeType; - if (rtType == null) + if (!(type is RuntimeType rtType)) throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type)); if (!rtType.IsDelegate()) @@ -415,42 +409,7 @@ namespace System return d; } - // Caution: this method is intended for deserialization only, no security checks are performed. - internal static Delegate CreateDelegateNoSecurityCheck(RuntimeType type, object firstArgument, MethodInfo method) - { - // Validate the parameters. - if (type == null) - throw new ArgumentNullException(nameof(type)); - if (method == null) - throw new ArgumentNullException(nameof(method)); - - - RuntimeMethodInfo rtMethod = method as RuntimeMethodInfo; - if (rtMethod == null) - throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(method)); - - if (!type.IsDelegate()) - throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type)); - - // This API is used by the formatters when deserializing a delegate. - // They pass us the specific target method (that was already the - // target in a valid delegate) so we should bind with the most - // relaxed rules available (the result will never be ambiguous, it - // just increases the chance of success with minor (compatible) - // signature changes). We explicitly skip security checks here -- - // we're not really constructing a delegate, we're cloning an - // existing instance which already passed its checks. - Delegate d = CreateDelegateInternal(type, rtMethod, firstArgument, - DelegateBindingFlags.SkipSecurityChecks | - DelegateBindingFlags.RelaxedSignature); - - if (d == null) - throw new ArgumentException(SR.Arg_DlgtTargMeth); - - return d; - } - - internal static Delegate CreateDelegateInternal(RuntimeType rtType, RuntimeMethodInfo rtMethod, object firstArgument, DelegateBindingFlags flags) + internal static Delegate? CreateDelegateInternal(RuntimeType rtType, RuntimeMethodInfo rtMethod, object? firstArgument, DelegateBindingFlags flags) { Delegate d = InternalAlloc(rtType); @@ -465,10 +424,10 @@ namespace System // [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern bool BindToMethodName(object target, RuntimeType methodType, string method, DelegateBindingFlags flags); + private extern bool BindToMethodName(object? target, RuntimeType methodType, string method, DelegateBindingFlags flags); [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern bool BindToMethodInfo(object target, IRuntimeMethodInfo method, RuntimeType methodType, DelegateBindingFlags flags); + private extern bool BindToMethodInfo(object? target, IRuntimeMethodInfo method, RuntimeType methodType, DelegateBindingFlags flags); [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern MulticastDelegate InternalAlloc(RuntimeType type); @@ -502,7 +461,7 @@ namespace System [MethodImplAttribute(MethodImplOptions.InternalCall)] internal extern IntPtr GetCallStub(IntPtr methodPtr); - internal virtual object GetTarget() + internal virtual object? GetTarget() { return (_methodPtrAux == IntPtr.Zero) ? _target : null; } diff --git a/src/System.Private.CoreLib/src/System/Enum.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Enum.CoreCLR.cs index c44bce1bba..0e9ab80f46 100644 --- a/src/System.Private.CoreLib/src/System/Enum.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Enum.CoreCLR.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; @@ -15,13 +16,13 @@ namespace System private static extern void GetEnumValuesAndNames(RuntimeTypeHandle enumType, ObjectHandleOnStack values, ObjectHandleOnStack names, bool getNames); [MethodImpl(MethodImplOptions.InternalCall)] - public override extern bool Equals(object obj); + public override extern bool Equals(object? obj); [MethodImpl(MethodImplOptions.InternalCall)] private static extern object InternalBoxEnum(RuntimeType enumType, long value); [MethodImpl(MethodImplOptions.InternalCall)] - private static extern int InternalCompareTo(object o1, object o2); + private static extern int InternalCompareTo(object thisRef, object? target); [MethodImpl(MethodImplOptions.InternalCall)] private extern CorElementType InternalGetCorElementType(); @@ -49,12 +50,12 @@ namespace System private static EnumInfo GetEnumInfo(RuntimeType enumType, bool getNames = true) { - EnumInfo entry = enumType.GenericCache as EnumInfo; + EnumInfo? entry = enumType.GenericCache as EnumInfo; if (entry == null || (getNames && entry.Names == null)) { - ulong[] values = null; - string[] names = null; + ulong[]? values = null; + string[]? names = null; GetEnumValuesAndNames( enumType.GetTypeHandleInternal(), JitHelpers.GetObjectHandleOnStack(ref values), @@ -62,7 +63,7 @@ namespace System getNames); bool hasFlagsAttribute = enumType.IsDefined(typeof(FlagsAttribute), inherit: false); - entry = new EnumInfo(hasFlagsAttribute, values, names); + entry = new EnumInfo(hasFlagsAttribute, values!, names!); enumType.GenericCache = entry; } @@ -95,7 +96,7 @@ namespace System return InternalHasFlag(flag); } - public static string GetName(Type enumType, object value) + public static string? GetName(Type enumType, object value) { if (enumType == null) throw new ArgumentNullException(nameof(enumType)); @@ -146,7 +147,7 @@ namespace System return rtType; } - public int CompareTo(object target) + public int CompareTo(object? target) { const int retIncompatibleMethodTables = 2; // indicates that the method tables did not match const int retInvalidEnumType = 3; // indicates that the enum was of an unknown/unsupported underlying type @@ -164,7 +165,7 @@ namespace System else if (ret == retIncompatibleMethodTables) { Type thisType = this.GetType(); - Type targetType = target.GetType(); + Type targetType = target!.GetType(); throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, targetType, thisType)); } diff --git a/src/System.Private.CoreLib/src/System/Exception.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Exception.CoreCLR.cs index d7228bdf32..c19aa643fc 100644 --- a/src/System.Private.CoreLib/src/System/Exception.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Exception.CoreCLR.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Collections; using System.Diagnostics; using System.Reflection; @@ -89,7 +90,7 @@ namespace System string restrictedError, string restrictedErrorReference, string restrictedCapabilitySid, - object restrictedErrorObject, + object? restrictedErrorObject, bool hasrestrictedLanguageErrorObject = false) { IDictionary dict = Data; @@ -106,7 +107,7 @@ namespace System } } - internal bool TryGetRestrictedLanguageErrorObject(out object restrictedErrorObject) + internal bool TryGetRestrictedLanguageErrorObject(out object? restrictedErrorObject) { restrictedErrorObject = null; if (Data != null && Data.Contains("__HasRestrictedLanguageErrorObject")) @@ -126,9 +127,10 @@ namespace System [MethodImplAttribute(MethodImplOptions.InternalCall)] static private extern IRuntimeMethodInfo GetMethodFromStackTrace(object stackTrace); - private MethodBase GetExceptionMethodFromStackTrace() + private MethodBase? GetExceptionMethodFromStackTrace() { - IRuntimeMethodInfo method = GetMethodFromStackTrace(_stackTrace); + Debug.Assert(_stackTrace != null, "_stackTrace shouldn't be null when this method is called"); + IRuntimeMethodInfo method = GetMethodFromStackTrace(_stackTrace!); // Under certain race conditions when exceptions are re-used, this can be null if (method == null) @@ -137,7 +139,7 @@ namespace System return RuntimeType.GetMethodBase(method); } - public MethodBase TargetSite + public MethodBase? TargetSite { get { @@ -157,7 +159,7 @@ namespace System // Returns the stack trace as a string. If no stack trace is // available, null is returned. - public virtual string StackTrace + public virtual string? StackTrace { get { @@ -171,10 +173,10 @@ namespace System // is true. Note that this requires FileIOPermission(PathDiscovery), and so // will usually fail in CoreCLR. To avoid the demand and resulting // SecurityException we can explicitly not even try to get fileinfo. - private string GetStackTrace(bool needFileInfo) + private string? GetStackTrace(bool needFileInfo) { - string stackTraceString = _stackTraceString; - string remoteStackTraceString = _remoteStackTraceString; + string? stackTraceString = _stackTraceString; + string? remoteStackTraceString = _remoteStackTraceString; // if no stack trace, try to get one if (stackTraceString != null) @@ -199,7 +201,7 @@ namespace System return new StackTrace(e, needFileInfo).ToString(System.Diagnostics.StackTrace.TraceFormat.Normal); } - private string CreateSourceName() + private string? CreateSourceName() { StackTrace st = new StackTrace(this, fNeedFileInfo: false); if (st.FrameCount > 0) @@ -209,12 +211,9 @@ namespace System Module module = method.Module; - RuntimeModule rtModule = module as RuntimeModule; - - if (rtModule == null) + if (!(module is RuntimeModule rtModule)) { - System.Reflection.Emit.ModuleBuilder moduleBuilder = module as System.Reflection.Emit.ModuleBuilder; - if (moduleBuilder != null) + if (module is System.Reflection.Emit.ModuleBuilder moduleBuilder) rtModule = moduleBuilder.InternalModule; else throw new ArgumentException(SR.Argument_MustBeRuntimeReflectionObject); @@ -246,7 +245,7 @@ namespace System // copy the stack trace to _remoteStackTraceString. internal void InternalPreserveStackTrace() { - string tmpStackTraceString; + string? tmpStackTraceString; #if FEATURE_APPX if (ApplicationModel.IsUap) @@ -258,13 +257,13 @@ namespace System // Make sure that the _source field is initialized if Source is not overriden. // We want it to contain the original faulting point. - string source = Source; + string? source = Source; } else #else // FEATURE_APPX // Preinitialize _source on CoreSystem as well. The legacy behavior is not ideal and // we keep it for back compat but we can afford to make the change on the Phone. - string source = Source; + string? source = Source; #endif // FEATURE_APPX { // Call the StackTrace getter in classic for compat. @@ -296,7 +295,7 @@ namespace System private static extern void GetStackTracesDeepCopy(Exception exception, out object currentStackTrace, out object dynamicMethodArray); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern void SaveStackTracesFromDeepCopy(Exception exception, object currentStackTrace, object dynamicMethodArray); + internal static extern void SaveStackTracesFromDeepCopy(Exception exception, object? currentStackTrace, object? dynamicMethodArray); [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern object CopyStackTrace(object currentStackTrace); @@ -307,7 +306,7 @@ namespace System [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern uint GetExceptionCount(); - internal object DeepCopyStackTrace(object currentStackTrace) + internal object? DeepCopyStackTrace(object? currentStackTrace) { if (currentStackTrace != null) { @@ -319,7 +318,7 @@ namespace System } } - internal object DeepCopyDynamicMethods(object currentDynamicMethods) + internal object? DeepCopyDynamicMethods(object? currentDynamicMethods) { if (currentDynamicMethods != null) { @@ -355,8 +354,8 @@ namespace System // // Since deep copying can throw on OOM, try to get the copies // outside the lock. - object _stackTraceCopy = (dispatchState.StackTrace == null) ? null : DeepCopyStackTrace(dispatchState.StackTrace); - object _dynamicMethodsCopy = (dispatchState.DynamicMethods == null) ? null : DeepCopyDynamicMethods(dispatchState.DynamicMethods); + object? _stackTraceCopy = (dispatchState.StackTrace == null) ? null : DeepCopyStackTrace(dispatchState.StackTrace); + object? _dynamicMethodsCopy = (dispatchState.DynamicMethods == null) ? null : DeepCopyDynamicMethods(dispatchState.DynamicMethods); // Finally, restore the information. // @@ -378,24 +377,24 @@ namespace System } } - private MethodBase _exceptionMethod; //Needed for serialization. - internal string _message; - private IDictionary _data; - private Exception _innerException; - private string _helpURL; - private object _stackTrace; - private object _watsonBuckets; - private string _stackTraceString; //Needed for serialization. - private string _remoteStackTraceString; + private MethodBase? _exceptionMethod; //Needed for serialization. + internal string? _message; + private IDictionary? _data; + private Exception? _innerException; + private string? _helpURL; + private object? _stackTrace; + private object? _watsonBuckets; + private string? _stackTraceString; //Needed for serialization. + private string? _remoteStackTraceString; #pragma warning disable 414 // Field is not used from managed. // _dynamicMethods is an array of System.Resolver objects, used to keep // DynamicMethodDescs alive for the lifetime of the exception. We do this because // the _stackTrace field holds MethodDescs, and a DynamicMethodDesc can be destroyed // unless a System.Resolver object roots it. - private object _dynamicMethods; + private object? _dynamicMethods; #pragma warning restore 414 - private string _source; // Mainly used by VB. + private string? _source; // Mainly used by VB. private UIntPtr _ipForWatsonBuckets; // Used to persist the IP for Watson Bucketing private IntPtr _xptrs; // Internal EE stuff #pragma warning disable 414 // Field is not used from managed. @@ -423,15 +422,15 @@ namespace System } } - private string SerializationRemoteStackTraceString => _remoteStackTraceString; + private string? SerializationRemoteStackTraceString => _remoteStackTraceString; - private object SerializationWatsonBuckets => _watsonBuckets; + private object? SerializationWatsonBuckets => _watsonBuckets; - private string SerializationStackTraceString + private string? SerializationStackTraceString { get { - string stackTraceString = _stackTraceString; + string? stackTraceString = _stackTraceString; if (stackTraceString == null && _stackTrace != null) { @@ -464,7 +463,7 @@ namespace System // See comment on ExceptionMessageKind internal static string GetMessageFromNativeResources(ExceptionMessageKind kind) { - string retMesg = null; + string? retMesg = null; GetMessageFromNativeResources(kind, JitHelpers.GetStringHandleOnStack(ref retMesg)); return retMesg; } @@ -474,18 +473,18 @@ namespace System internal readonly struct DispatchState { - public readonly object StackTrace; - public readonly object DynamicMethods; - public readonly string RemoteStackTrace; + public readonly object? StackTrace; + public readonly object? DynamicMethods; + public readonly string? RemoteStackTrace; public readonly UIntPtr IpForWatsonBuckets; - public readonly object WatsonBuckets; + public readonly object? WatsonBuckets; public DispatchState( - object stackTrace, - object dynamicMethods, - string remoteStackTrace, + object? stackTrace, + object? dynamicMethods, + string? remoteStackTrace, UIntPtr ipForWatsonBuckets, - object watsonBuckets) + object? watsonBuckets) { StackTrace = stackTrace; DynamicMethods = dynamicMethods; @@ -497,7 +496,7 @@ namespace System internal DispatchState CaptureDispatchState() { - GetStackTracesDeepCopy(this, out object stackTrace, out object dynamicMethods); + GetStackTracesDeepCopy(this, out object? stackTrace, out object? dynamicMethods); return new DispatchState(stackTrace, dynamicMethods, _remoteStackTraceString, _ipForWatsonBuckets, _watsonBuckets); diff --git a/src/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs b/src/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs index ef593b974d..9da8e35f29 100644 --- a/src/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs @@ -2,17 +2,16 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Globalization; -using System.Runtime.InteropServices; +#nullable enable using System.Runtime.CompilerServices; -using System.Security; +using System.Runtime.InteropServices; namespace System.IO { public partial class FileLoadException { // Do not delete: this is invoked from native code. - private FileLoadException(string fileName, string fusionLog, int hResult) + private FileLoadException(string? fileName, string? fusionLog, int hResult) : base(null) { HResult = hResult; @@ -21,12 +20,12 @@ namespace System.IO _message = FormatFileLoadExceptionMessage(FileName, HResult); } - internal static string FormatFileLoadExceptionMessage(string fileName, int hResult) + internal static string FormatFileLoadExceptionMessage(string? fileName, int hResult) { - string format = null; + string? format = null; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 GetStringHandleOnStack needs to be attributed GetFileLoadExceptionMessage(hResult, JitHelpers.GetStringHandleOnStack(ref format)); - string message = null; + string? message = null; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 GetStringHandleOnStack needs to be attributed if (hResult == System.HResults.COR_E_BADEXEFORMAT) message = SR.Arg_BadImageFormatException; else diff --git a/src/System.Private.CoreLib/src/System/IO/FileNotFoundException.CoreCLR.cs b/src/System.Private.CoreLib/src/System/IO/FileNotFoundException.CoreCLR.cs index 99645f0f2d..c20b0d798a 100644 --- a/src/System.Private.CoreLib/src/System/IO/FileNotFoundException.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/IO/FileNotFoundException.CoreCLR.cs @@ -2,12 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.IO { public partial class FileNotFoundException { // Do not delete: this is invoked from native code. - private FileNotFoundException(string fileName, string fusionLog, int hResult) + private FileNotFoundException(string? fileName, string? fusionLog, int hResult) : base(null) { HResult = hResult; @@ -17,4 +18,3 @@ namespace System.IO } } } - diff --git a/src/System.Private.CoreLib/src/System/IO/Stream.CoreCLR.cs b/src/System.Private.CoreLib/src/System/IO/Stream.CoreCLR.cs index 459e991bf7..14434ca8f2 100644 --- a/src/System.Private.CoreLib/src/System/IO/Stream.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/IO/Stream.CoreCLR.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; namespace System.IO diff --git a/src/System.Private.CoreLib/src/System/MissingMemberException.CoreCLR.cs b/src/System.Private.CoreLib/src/System/MissingMemberException.CoreCLR.cs index 9c532cf4cc..e987f4175e 100644 --- a/src/System.Private.CoreLib/src/System/MissingMemberException.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/MissingMemberException.CoreCLR.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.Serialization; using System.Runtime.CompilerServices; @@ -10,6 +11,6 @@ namespace System public partial class MissingMemberException : MemberAccessException, ISerializable { [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern string FormatSignature(byte[] signature); + internal static extern string FormatSignature(byte[]? signature); } } diff --git a/src/System.Private.CoreLib/src/System/MulticastDelegate.cs b/src/System.Private.CoreLib/src/System/MulticastDelegate.cs index 40f9478c64..e128c7597b 100644 --- a/src/System.Private.CoreLib/src/System/MulticastDelegate.cs +++ b/src/System.Private.CoreLib/src/System/MulticastDelegate.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; @@ -20,7 +21,7 @@ namespace System // 1. Multicast delegate // 2. Secure/Wrapper delegate // 3. Inner delegate of secure delegate where the secure delegate security context is a collectible method - private object _invocationList; + private object? _invocationList; // Initialized by VM as needed private IntPtr _invocationCount; // This constructor is called from the class generated by the @@ -54,7 +55,7 @@ namespace System // equals returns true IIF the delegate is not null and has the // same target, method and invocation list as this object - public override sealed bool Equals(object obj) + public override sealed bool Equals(object? obj) { if (obj == null) return false; @@ -96,10 +97,10 @@ namespace System } else { - if ((_invocationList as Delegate) != null) + if (_invocationList is Delegate invocationListDelegate) { // this is a secure/wrapper delegate so we need to unwrap and check the inner one - return _invocationList.Equals(obj); + return invocationListDelegate.Equals(obj); } else { @@ -116,7 +117,7 @@ namespace System // and call the base.Equals() if (!InvocationListLogicallyNull()) { - if (!_invocationList.Equals(d._invocationList)) + if (!_invocationList!.Equals(d._invocationList)) return false; return base.Equals(d); } @@ -134,25 +135,29 @@ namespace System // Recursive function which will check for equality of the invocation list. private bool InvocationListEquals(MulticastDelegate d) { - Debug.Assert(d != null && (_invocationList as object[]) != null, "bogus delegate in multicast list comparison"); - object[] invocationList = _invocationList as object[]; + Debug.Assert(d != null); + Debug.Assert(_invocationList is object[]); + object[] invocationList = (object[])_invocationList; + if (d._invocationCount != _invocationCount) return false; int invocationCount = (int)_invocationCount; for (int i = 0; i < invocationCount; i++) { - Delegate dd = (Delegate)invocationList[i]; - object[] dInvocationList = d._invocationList as object[]; + Debug.Assert(invocationList[i] is Delegate); + Delegate dd = (Delegate)invocationList[i]; // If invocationList is an object[], it always contains Delegate (or MulticastDelegate) objects + + object[] dInvocationList = (d._invocationList as object[])!; if (!dd.Equals(dInvocationList[i])) return false; } return true; } - private bool TrySetSlot(object[] a, int index, object o) + private bool TrySetSlot(object?[] a, int index, object o) { - if (a[index] == null && System.Threading.Interlocked.CompareExchange<object>(ref a[index], o, null) == null) + if (a[index] == null && System.Threading.Interlocked.CompareExchange<object?>(ref a[index], o, null) == null) return true; // The slot may be already set because we have added and removed the same method before. @@ -160,7 +165,7 @@ namespace System if (a[index] != null) { MulticastDelegate d = (MulticastDelegate)o; - MulticastDelegate dd = (MulticastDelegate)a[index]; + MulticastDelegate dd = (MulticastDelegate)a[index]!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/34644 if (dd._methodPtr == d._methodPtr && dd._target == d._target && @@ -207,7 +212,7 @@ namespace System { Debug.Assert(!IsUnmanagedFunctionPtr(), "dynamic method and unmanaged fntptr delegate combined"); // must be a secure/wrapper one, unwrap and save - MulticastDelegate d = (MulticastDelegate)_invocationList; + MulticastDelegate d = ((MulticastDelegate?)_invocationList)!; d._methodBase = dynamicMethod; } else @@ -216,9 +221,9 @@ namespace System // This method will combine this delegate with the passed delegate // to form a new delegate. - protected override sealed Delegate CombineImpl(Delegate follow) + protected override sealed Delegate CombineImpl(Delegate? follow) { - if ((object)follow == null) // cast to object for a more efficient test + if ((object?)follow == null) // cast to object for a more efficient test return this; // Verify that the types are the same... @@ -226,9 +231,9 @@ namespace System throw new ArgumentException(SR.Arg_DlgtTypeMis); MulticastDelegate dFollow = (MulticastDelegate)follow; - object[] resultList; + object[]? resultList; int followCount = 1; - object[] followList = dFollow._invocationList as object[]; + object[]? followList = dFollow._invocationList as object[]; if (followList != null) followCount = (int)dFollow._invocationCount; @@ -302,7 +307,8 @@ namespace System private object[] DeleteFromInvocationList(object[] invocationList, int invocationCount, int deleteIndex, int deleteCount) { - object[] thisInvocationList = _invocationList as object[]; + Debug.Assert(_invocationList is object[]); + object[] thisInvocationList = (object[])_invocationList; int allocCount = thisInvocationList.Length; while (allocCount / 2 >= invocationCount - deleteCount) allocCount /= 2; @@ -333,12 +339,12 @@ namespace System // look at the invocation list.) If this is found we remove it from // this list and return a new delegate. If its not found a copy of the // current list is returned. - protected override sealed Delegate RemoveImpl(Delegate value) + protected override sealed Delegate? RemoveImpl(Delegate value) { // There is a special case were we are removing using a delegate as // the value we need to check for this case // - MulticastDelegate v = value as MulticastDelegate; + MulticastDelegate? v = value as MulticastDelegate; if (v == null) return this; @@ -379,7 +385,7 @@ namespace System int vInvocationCount = (int)v._invocationCount; for (int i = invocationCount - vInvocationCount; i >= 0; i--) { - if (EqualInvocationLists(invocationList, v._invocationList as object[], i, vInvocationCount)) + if (EqualInvocationLists(invocationList, (v._invocationList as object[])!, i, vInvocationCount)) { if (invocationCount - vInvocationCount == 0) { @@ -427,7 +433,7 @@ namespace System // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(MulticastDelegate d1, MulticastDelegate d2) + public static bool operator ==(MulticastDelegate? d1, MulticastDelegate? d2) { // Test d2 first to allow branch elimination when inlined for null checks (== null) // so it can become a simple test @@ -437,12 +443,12 @@ namespace System return (d1 is null) ? true : false; } - return ReferenceEquals(d2, d1) ? true : d2.Equals((object)d1); + return ReferenceEquals(d2, d1) ? true : d2.Equals((object?)d1); } // Force inline as the true/false ternary takes it above ALWAYS_INLINE size even though the asm ends up smaller [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(MulticastDelegate d1, MulticastDelegate d2) + public static bool operator !=(MulticastDelegate? d1, MulticastDelegate? d2) { // Can't call the == operator as it will call object== @@ -487,7 +493,7 @@ namespace System } } - internal override object GetTarget() + internal override object? GetTarget() { if (_invocationCount != (IntPtr)0) { @@ -528,8 +534,8 @@ namespace System int index = (int)_invocationCount - 1; return ((Delegate)invocationList[index]).Method; } - MulticastDelegate innerDelegate = _invocationList as MulticastDelegate; - if (innerDelegate != null) + + if (_invocationList is MulticastDelegate innerDelegate) { // must be a secure/wrapper delegate return innerDelegate.GetMethodImpl(); @@ -548,7 +554,7 @@ namespace System if (RuntimeTypeHandle.IsGenericTypeDefinition(declaringType) || RuntimeTypeHandle.HasInstantiation(declaringType)) { // we are returning the 'Invoke' method of this delegate so use this.GetType() for the exact type - RuntimeType reflectedType = GetType() as RuntimeType; + RuntimeType reflectedType = (RuntimeType)GetType(); declaringType = reflectedType; } _methodBase = (MethodInfo)RuntimeType.GetMethodBase(declaringType, method); @@ -572,7 +578,7 @@ namespace System { if (target == null) ThrowNullThisInDelegateToInstance(); - this._target = target; + this._target = target!; // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/538 this._methodPtr = methodPtr; } diff --git a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandle.Unix.cs b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandle.Unix.cs index b7cdaa801c..29f53337b9 100644 --- a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandle.Unix.cs +++ b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandle.Unix.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandle.Windows.cs b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandle.Windows.cs index a40661c1b6..d2f46cc9f6 100644 --- a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandle.Windows.cs +++ b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandle.Windows.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +#nullable enable using System.Diagnostics; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandle.cs b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandle.cs index 4264b91943..38636f308f 100644 --- a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandle.cs +++ b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandle.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Runtime.InteropServices; @@ -128,7 +129,7 @@ namespace System.Threading /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed. /// </exception> [CLSCompliant(false)] - public unsafe NativeOverlapped* AllocateNativeOverlapped(IOCompletionCallback callback, object state, object pinData) + public unsafe NativeOverlapped* AllocateNativeOverlapped(IOCompletionCallback callback, object? state, object? pinData) { if (callback == null) throw new ArgumentNullException(nameof(callback)); @@ -254,7 +255,7 @@ namespace System.Threading /// <paramref name="overlapped"/> is <see langword="null"/>. /// </exception> [CLSCompliant(false)] - public static unsafe object GetNativeOverlappedState(NativeOverlapped* overlapped) + public static unsafe object? GetNativeOverlappedState(NativeOverlapped* overlapped) { if (overlapped == null) throw new ArgumentNullException(nameof(overlapped)); @@ -264,7 +265,7 @@ namespace System.Threading return wrapper._userState; } - private static unsafe ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped* overlapped, ThreadPoolBoundHandle expectedBoundHandle) + private static unsafe ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped* overlapped, ThreadPoolBoundHandle? expectedBoundHandle) { ThreadPoolBoundHandleOverlapped wrapper; try diff --git a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs index 7ce8936bf7..a61d69e559 100644 --- a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs +++ b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { /// <summary> @@ -12,13 +13,13 @@ namespace System.Threading private static readonly unsafe IOCompletionCallback s_completionCallback = CompletionCallback; private readonly IOCompletionCallback _userCallback; - internal readonly object _userState; - internal PreAllocatedOverlapped _preAllocated; + internal readonly object? _userState; + internal PreAllocatedOverlapped? _preAllocated; internal unsafe NativeOverlapped* _nativeOverlapped; - internal ThreadPoolBoundHandle _boundHandle; + internal ThreadPoolBoundHandle? _boundHandle; internal bool _completed; - public unsafe ThreadPoolBoundHandleOverlapped(IOCompletionCallback callback, object state, object pinData, PreAllocatedOverlapped preAllocated) + public unsafe ThreadPoolBoundHandleOverlapped(IOCompletionCallback callback, object? state, object? pinData, PreAllocatedOverlapped? preAllocated) { _userCallback = callback; _userState = state; diff --git a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs index 64c7219135..26e1bd6bee 100644 --- a/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs +++ b/src/System.Private.CoreLib/src/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { /// <summary> @@ -48,7 +49,7 @@ namespace System.Threading /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed. /// </exception> [CLSCompliant(false)] - public PreAllocatedOverlapped(IOCompletionCallback callback, object state, object pinData) + public PreAllocatedOverlapped(IOCompletionCallback callback, object? state, object? pinData) { if (callback == null) throw new ArgumentNullException(nameof(callback)); @@ -87,7 +88,7 @@ namespace System.Threading unsafe void IDeferredDisposable.OnFinalRelease(bool disposed) { - if (_overlapped != null) + if (_overlapped != null) // protect against ctor throwing exception and leaving field uninitialized { if (disposed) { diff --git a/src/System.Private.CoreLib/src/System/Threading/Interlocked.cs b/src/System.Private.CoreLib/src/System/Threading/Interlocked.cs index 8744b4ccaf..844c888b97 100644 --- a/src/System.Private.CoreLib/src/System/Threading/Interlocked.cs +++ b/src/System.Private.CoreLib/src/System/Threading/Interlocked.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using Internal.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -59,7 +60,7 @@ namespace System.Threading public static extern double Exchange(ref double location1, double value); [MethodImplAttribute(MethodImplOptions.InternalCall)] - public static extern object Exchange(ref object location1, object value); + public static extern object? Exchange(ref object? location1, object? value); [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern IntPtr Exchange(ref IntPtr location1, IntPtr value); @@ -67,9 +68,9 @@ namespace System.Threading // This whole method reduces to a single call to Exchange(ref object, object) but // the JIT thinks that it will generate more native code than it actually does. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T Exchange<T>(ref T location1, T value) where T : class + public static T Exchange<T>(ref T location1, T value) where T : class? { - return Unsafe.As<T>(Exchange(ref Unsafe.As<T, object>(ref location1), value)); + return Unsafe.As<T>(Exchange(ref Unsafe.As<T, object?>(ref location1), value)); } /// <summary> @@ -88,7 +89,7 @@ namespace System.Threading public static extern double CompareExchange(ref double location1, double value, double comparand); [MethodImplAttribute(MethodImplOptions.InternalCall)] - public static extern object CompareExchange(ref object location1, object value, object comparand); + public static extern object? CompareExchange(ref object? location1, object? value, object? comparand); [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern IntPtr CompareExchange(ref IntPtr location1, IntPtr value, IntPtr comparand); @@ -102,9 +103,9 @@ namespace System.Threading // ret // The workaround is no longer strictly necessary now that we have Unsafe.As but it does // have the advantage of being less sensitive to JIT's inliner decisions. - public static T CompareExchange<T>(ref T location1, T value, T comparand) where T : class + public static T CompareExchange<T>(ref T location1, T value, T comparand) where T : class? { - return Unsafe.As<T>(CompareExchange(ref Unsafe.As<T, object>(ref location1), value, comparand)); + return Unsafe.As<T>(CompareExchange(ref Unsafe.As<T, object?>(ref location1), value, comparand)); } // BCL-internal overload that returns success via a ref bool param, useful for reliable spin locks. diff --git a/src/System.Private.CoreLib/src/System/Threading/Monitor.cs b/src/System.Private.CoreLib/src/System/Threading/Monitor.cs index 2837d908c6..2701b3b555 100644 --- a/src/System.Private.CoreLib/src/System/Threading/Monitor.cs +++ b/src/System.Private.CoreLib/src/System/Threading/Monitor.cs @@ -13,8 +13,7 @@ ** =============================================================================*/ - - +#nullable enable using System; using System.Runtime; using System.Threading; diff --git a/src/System.Private.CoreLib/src/System/Threading/Overlapped.cs b/src/System.Private.CoreLib/src/System/Threading/Overlapped.cs index d43c78d8f7..e21d808b64 100644 --- a/src/System.Private.CoreLib/src/System/Threading/Overlapped.cs +++ b/src/System.Private.CoreLib/src/System/Threading/Overlapped.cs @@ -21,7 +21,7 @@ ** =============================================================================*/ - +#nullable enable using System.Diagnostics; using System.Runtime.CompilerServices; @@ -67,7 +67,8 @@ namespace System.Threading else { // We got here because of Pack - var helper = (_IOCompletionCallback)overlapped._callback; + var helper = (_IOCompletionCallback?)overlapped._callback; + Debug.Assert(helper != null, "Should only be receiving a completion callback if a delegate was provided."); helper._errorCode = errorCode; helper._numBytes = numBytes; helper._pNativeOverlapped = pNativeOverlapped; @@ -89,22 +90,22 @@ namespace System.Threading { // ! If you make any change to the layout here, you need to make matching change // ! to OverlappedDataObject in vm\nativeoverlapped.h - internal IAsyncResult _asyncResult; - internal object _callback; // IOCompletionCallback or _IOCompletionCallback - internal Overlapped _overlapped; - private object _userObject; + internal IAsyncResult? _asyncResult; + internal object? _callback; // IOCompletionCallback or _IOCompletionCallback + internal readonly Overlapped _overlapped; + private object? _userObject; private NativeOverlapped * _pNativeOverlapped; private IntPtr _eventHandle; private int _offsetLow; private int _offsetHigh; - internal ref IAsyncResult AsyncResult => ref _asyncResult; + internal OverlappedData(Overlapped overlapped) => _overlapped = overlapped; internal ref int OffsetLow => ref (_pNativeOverlapped != null) ? ref _pNativeOverlapped->OffsetLow : ref _offsetLow; internal ref int OffsetHigh => ref (_pNativeOverlapped != null) ? ref _pNativeOverlapped->OffsetHigh : ref _offsetHigh; internal ref IntPtr EventHandle => ref (_pNativeOverlapped != null) ? ref _pNativeOverlapped->EventHandle : ref _eventHandle; - internal unsafe NativeOverlapped* Pack(IOCompletionCallback iocb, object userData) + internal unsafe NativeOverlapped* Pack(IOCompletionCallback? iocb, object? userData) { if (_pNativeOverlapped != null) { @@ -113,7 +114,7 @@ namespace System.Threading if (iocb != null) { - ExecutionContext ec = ExecutionContext.Capture(); + ExecutionContext? ec = ExecutionContext.Capture(); _callback = (ec != null && !ec.IsDefault) ? new _IOCompletionCallback(iocb, ec) : (object)iocb; } else @@ -124,7 +125,7 @@ namespace System.Threading return AllocateNativeOverlapped(); } - internal unsafe NativeOverlapped* UnsafePack(IOCompletionCallback iocb, object userData) + internal unsafe NativeOverlapped* UnsafePack(IOCompletionCallback? iocb, object? userData) { if (_pNativeOverlapped != null) { @@ -155,22 +156,22 @@ namespace System.Threading public class Overlapped { - private OverlappedData _overlappedData; + private OverlappedData? _overlappedData; public Overlapped() { // The split between Overlapped and OverlappedData should not be needed. It is required by the implementation of // async GC handles currently. It expects OverlappedData to be a sealed type. - _overlappedData = new OverlappedData(); - _overlappedData._overlapped = this; + _overlappedData = new OverlappedData(this); } public Overlapped(int offsetLo, int offsetHi, IntPtr hEvent, IAsyncResult ar) : this() { + Debug.Assert(_overlappedData != null, "Initialized in delegated ctor"); _overlappedData.OffsetLow = offsetLo; _overlappedData.OffsetHigh = offsetHi; _overlappedData.EventHandle = hEvent; - _overlappedData.AsyncResult = ar; + _overlappedData._asyncResult = ar; } [Obsolete("This constructor is not 64-bit compatible. Use the constructor that takes an IntPtr for the event handle. http://go.microsoft.com/fwlink/?linkid=14202")] @@ -178,22 +179,22 @@ namespace System.Threading { } - public IAsyncResult AsyncResult + public IAsyncResult? AsyncResult { - get { return _overlappedData.AsyncResult; } - set { _overlappedData.AsyncResult = value; } + get { return _overlappedData!._asyncResult; } + set { _overlappedData!._asyncResult = value; } } public int OffsetLow { - get { return _overlappedData.OffsetLow; } - set { _overlappedData.OffsetLow = value; } + get { return _overlappedData!.OffsetLow; } + set { _overlappedData!.OffsetLow = value; } } public int OffsetHigh { - get { return _overlappedData.OffsetHigh; } - set { _overlappedData.OffsetHigh = value; } + get { return _overlappedData!.OffsetHigh; } + set { _overlappedData!.OffsetHigh = value; } } [Obsolete("This property is not 64-bit compatible. Use EventHandleIntPtr instead. http://go.microsoft.com/fwlink/?linkid=14202")] @@ -205,8 +206,8 @@ namespace System.Threading public IntPtr EventHandleIntPtr { - get { return _overlappedData.EventHandle; } - set { _overlappedData.EventHandle = value; } + get { return _overlappedData!.EventHandle; } + set { _overlappedData!.EventHandle = value; } } /*==================================================================== @@ -216,28 +217,28 @@ namespace System.Threading ====================================================================*/ [Obsolete("This method is not safe. Use Pack (iocb, userData) instead. http://go.microsoft.com/fwlink/?linkid=14202")] [CLSCompliant(false)] - public unsafe NativeOverlapped* Pack(IOCompletionCallback iocb) + public unsafe NativeOverlapped* Pack(IOCompletionCallback? iocb) { return Pack(iocb, null); } [CLSCompliant(false)] - public unsafe NativeOverlapped* Pack(IOCompletionCallback iocb, object userData) + public unsafe NativeOverlapped* Pack(IOCompletionCallback? iocb, object? userData) { - return _overlappedData.Pack(iocb, userData); + return _overlappedData!.Pack(iocb, userData); } [Obsolete("This method is not safe. Use UnsafePack (iocb, userData) instead. http://go.microsoft.com/fwlink/?linkid=14202")] [CLSCompliant(false)] - public unsafe NativeOverlapped* UnsafePack(IOCompletionCallback iocb) + public unsafe NativeOverlapped* UnsafePack(IOCompletionCallback? iocb) { return UnsafePack(iocb, null); } [CLSCompliant(false)] - public unsafe NativeOverlapped* UnsafePack(IOCompletionCallback iocb, object userData) + public unsafe NativeOverlapped* UnsafePack(IOCompletionCallback? iocb, object? userData) { - return _overlappedData.UnsafePack(iocb, userData); + return _overlappedData!.UnsafePack(iocb, userData); } /*==================================================================== diff --git a/src/System.Private.CoreLib/src/System/Threading/StackCrawlMark.cs b/src/System.Private.CoreLib/src/System/Threading/StackCrawlMark.cs index 7323d1dced..977cccb833 100644 --- a/src/System.Private.CoreLib/src/System/Threading/StackCrawlMark.cs +++ b/src/System.Private.CoreLib/src/System/Threading/StackCrawlMark.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { /// <summary> diff --git a/src/System.Private.CoreLib/src/System/Threading/SynchronizationContext.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Threading/SynchronizationContext.CoreCLR.cs index e26d9b7b70..db110279db 100644 --- a/src/System.Private.CoreLib/src/System/Threading/SynchronizationContext.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Threading/SynchronizationContext.CoreCLR.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable namespace System.Threading { public partial class SynchronizationContext diff --git a/src/System.Private.CoreLib/src/System/Threading/SynchronizationContext.Uap.cs b/src/System.Private.CoreLib/src/System/Threading/SynchronizationContext.Uap.cs index a9f0727771..b04f93e516 100644 --- a/src/System.Private.CoreLib/src/System/Threading/SynchronizationContext.Uap.cs +++ b/src/System.Private.CoreLib/src/System/Threading/SynchronizationContext.Uap.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Reflection; @@ -11,11 +12,11 @@ namespace System.Threading { public partial class SynchronizationContext { - public static SynchronizationContext Current + public static SynchronizationContext? Current { get { - SynchronizationContext context = Thread.CurrentThread._synchronizationContext; + SynchronizationContext? context = Thread.CurrentThread._synchronizationContext; if (context == null && ApplicationModel.IsUap) context = GetWinRTContext(); @@ -24,7 +25,7 @@ namespace System.Threading } } - private static SynchronizationContext GetWinRTContext() + private static SynchronizationContext? GetWinRTContext() { Debug.Assert(Environment.IsWinRTSupported); Debug.Assert(ApplicationModel.IsUap); @@ -39,14 +40,14 @@ namespace System.Threading // So, we check the VM to see if the current thread has a dispatcher; if it does, we pass that along to // System.Runtime.WindowsRuntime to get a corresponding SynchronizationContext. // - object dispatcher = GetWinRTDispatcherForCurrentThread(); + object? dispatcher = GetWinRTDispatcherForCurrentThread(); if (dispatcher != null) return GetWinRTSynchronizationContext(dispatcher); return null; } - private static Func<object, SynchronizationContext> s_createSynchronizationContextDelegate; + private static Func<object, SynchronizationContext>? s_createSynchronizationContextDelegate; private static SynchronizationContext GetWinRTSynchronizationContext(object dispatcher) { @@ -55,23 +56,23 @@ namespace System.Threading // It would be better if we could just implement WinRTSynchronizationContextFactory in mscorlib, but we can't, because // we can do very little with WinRT stuff in mscorlib. // - Func<object, SynchronizationContext> createSynchronizationContextDelegate = s_createSynchronizationContextDelegate; + Func<object, SynchronizationContext>? createSynchronizationContextDelegate = s_createSynchronizationContextDelegate; if (createSynchronizationContextDelegate == null) { Type factoryType = Type.GetType("System.Threading.WinRTSynchronizationContextFactory, System.Runtime.WindowsRuntime", throwOnError: true); // Create an instance delegate for the Create static method MethodInfo createMethodInfo = factoryType.GetMethod("Create", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); - createSynchronizationContextDelegate = (Func<object, SynchronizationContext>)Delegate.CreateDelegate(typeof(Func<object, SynchronizationContext>), createMethodInfo, /* throwOnBindFailure */ true); + createSynchronizationContextDelegate = (Func<object, SynchronizationContext>)Delegate.CreateDelegate(typeof(Func<object, SynchronizationContext>), createMethodInfo); s_createSynchronizationContextDelegate = createSynchronizationContextDelegate; } - return s_createSynchronizationContextDelegate(dispatcher); + return createSynchronizationContextDelegate(dispatcher); } [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Interface)] - private static extern object GetWinRTDispatcherForCurrentThread(); + private static extern object? GetWinRTDispatcherForCurrentThread(); } } diff --git a/src/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs b/src/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs index d72ca12b70..491916699f 100644 --- a/src/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs +++ b/src/System.Private.CoreLib/src/System/Threading/Tasks/AsyncCausalityTracer.cs @@ -2,16 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Security; +#nullable enable using System.Diagnostics; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - using System.Runtime.InteropServices.WindowsRuntime; - using WFD = Windows.Foundation.Diagnostics; - namespace System.Threading.Tasks { internal static class AsyncCausalityTracer @@ -64,7 +60,7 @@ namespace System.Threading.Tasks //COM Interface GUID {50850B26-267E-451B-A890-AB6A370245EE} Guid guid = new Guid(0x50850B26, 0x267E, 0x451B, 0xA8, 0x90, 0XAB, 0x6A, 0x37, 0x02, 0x45, 0xEE); - object factory = null; + object? factory = null; try { diff --git a/src/System.Private.CoreLib/src/System/Threading/Tasks/IAsyncCausalityTracerStatics.cs b/src/System.Private.CoreLib/src/System/Threading/Tasks/IAsyncCausalityTracerStatics.cs index a09279c06c..131fffc348 100644 --- a/src/System.Private.CoreLib/src/System/Threading/Tasks/IAsyncCausalityTracerStatics.cs +++ b/src/System.Private.CoreLib/src/System/Threading/Tasks/IAsyncCausalityTracerStatics.cs @@ -2,9 +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.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs index 4ab1cc98d4..a3bd3c6698 100644 --- a/src/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; @@ -14,29 +15,31 @@ namespace System.Threading internal sealed class ThreadHelper { private Delegate _start; - internal CultureInfo _startCulture; - internal CultureInfo _startUICulture; - private object _startArg = null; - private ExecutionContext _executionContext = null; + internal CultureInfo? _startCulture; + internal CultureInfo? _startUICulture; + private object? _startArg = null; + private ExecutionContext? _executionContext = null; internal ThreadHelper(Delegate start) { _start = start; } - internal void SetExecutionContextHelper(ExecutionContext ec) + internal void SetExecutionContextHelper(ExecutionContext? ec) { _executionContext = ec; } internal static readonly ContextCallback s_threadStartContextCallback = new ContextCallback(ThreadStart_Context); - private static void ThreadStart_Context(object state) + private static void ThreadStart_Context(object? state) { + Debug.Assert(state is ThreadHelper); ThreadHelper t = (ThreadHelper)state; t.InitializeCulture(); + Debug.Assert(t._start is ThreadStart || t._start is ParameterizedThreadStart); if (t._start is ThreadStart threadStart) { threadStart(); @@ -63,11 +66,12 @@ namespace System.Threading } // call back helper - internal void ThreadStart(object obj) + internal void ThreadStart(object? obj) { + Debug.Assert(_start is ParameterizedThreadStart); _startArg = obj; - - ExecutionContext context = _executionContext; + + ExecutionContext? context = _executionContext; if (context != null) { ExecutionContext.RunInternal(context, s_threadStartContextCallback, this); @@ -82,7 +86,9 @@ namespace System.Threading // call back helper internal void ThreadStart() { - ExecutionContext context = _executionContext; + Debug.Assert(_start is ThreadStart); + + ExecutionContext? context = _executionContext; if (context != null) { ExecutionContext.RunInternal(context, s_threadStartContextCallback, this); @@ -112,13 +118,13 @@ namespace System.Threading ** ThreadBaseObject to maintain alignment between the two classes. ** DON'T CHANGE THESE UNLESS YOU MODIFY ThreadBaseObject in vm\object.h =========================================================================*/ - internal ExecutionContext _executionContext; // this call context follows the logical thread - internal SynchronizationContext _synchronizationContext; // maintained separately from ExecutionContext + internal ExecutionContext? _executionContext; // this call context follows the logical thread + internal SynchronizationContext? _synchronizationContext; // maintained separately from ExecutionContext - private string _name; - private Delegate _delegate; // Delegate + private string? _name; + private Delegate? _delegate; // Delegate - private object _threadStartArg; + private object? _threadStartArg; /*========================================================================= ** The base implementation of Thread is all native. The following fields @@ -179,7 +185,7 @@ namespace System.Threading /// method on the IThreadable interface passed in the constructor. Once the /// thread is dead, it cannot be restarted with another call to Start. /// </summary> - public void Start(object parameter) + public void Start(object? parameter) { // In the case of a null delegate (second call to start on same thread) // StartInternal method will take care of the error reporting. @@ -207,8 +213,10 @@ namespace System.Threading { // If we reach here with a null delegate, something is broken. But we'll let the StartInternal method take care of // reporting an error. Just make sure we don't try to dereference a null delegate. - ThreadHelper t = (ThreadHelper)_delegate.Target; - ExecutionContext ec = ExecutionContext.Capture(); + Debug.Assert(_delegate.Target is ThreadHelper); + var t = (ThreadHelper)_delegate.Target; + + ExecutionContext? ec = ExecutionContext.Capture(); t.SetExecutionContextHelper(ec); } @@ -218,8 +226,10 @@ namespace System.Threading private void SetCultureOnUnstartedThreadNoCheck(CultureInfo value, bool uiCulture) { Debug.Assert(_delegate != null); + Debug.Assert(_delegate.Target is ThreadHelper); + + var t = (ThreadHelper)(_delegate.Target); - ThreadHelper t = (ThreadHelper)(_delegate.Target); if (uiCulture) { t._startUICulture = value; @@ -274,14 +284,14 @@ namespace System.Threading { Debug.Assert(maxStackSize >= 0); - var threadStartCallBack = new ThreadHelper(start); + var helper = new ThreadHelper(start); if (start is ThreadStart) { - SetStart(new ThreadStart(threadStartCallBack.ThreadStart), maxStackSize); + SetStart(new ThreadStart(helper.ThreadStart), maxStackSize); } else { - SetStart(new ParameterizedThreadStart(threadStartCallBack.ThreadStart), maxStackSize); + SetStart(new ParameterizedThreadStart(helper.ThreadStart), maxStackSize); } } @@ -300,13 +310,13 @@ namespace System.Threading private extern void StartupSetApartmentStateInternal(); #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT - partial void ThreadNameChanged(string value) + partial void ThreadNameChanged(string? value) { InformThreadNameChange(GetNativeHandle(), value, value?.Length ?? 0); } [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] - private static extern void InformThreadNameChange(ThreadHandle t, string name, int len); + private static extern void InformThreadNameChange(ThreadHandle t, string? name, int len); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern DeserializationTracker GetThreadDeserializationTracker(ref StackCrawlMark stackMark); diff --git a/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs index 02dedbf6e1..89030787ed 100644 --- a/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs @@ -11,6 +11,8 @@ ** =============================================================================*/ +#nullable enable +using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; @@ -32,7 +34,7 @@ namespace System.Threading { private static IntPtr InvalidHandle => new IntPtr(-1); private IntPtr registeredWaitHandle = InvalidHandle; - private WaitHandle m_internalWaitObject; + private WaitHandle? m_internalWaitObject; private bool bReleaseNeeded = false; private volatile int m_lock = 0; @@ -51,12 +53,12 @@ namespace System.Threading m_internalWaitObject = waitObject; if (waitObject != null) { - m_internalWaitObject.SafeWaitHandle.DangerousAddRef(ref bReleaseNeeded); + m_internalWaitObject.SafeWaitHandle!.DangerousAddRef(ref bReleaseNeeded); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/2384 } } internal bool Unregister( - WaitHandle waitObject // object to be notified when all callbacks to delegates have completed + WaitHandle? waitObject // object to be notified when all callbacks to delegates have completed ) { bool result = false; @@ -80,7 +82,8 @@ namespace System.Threading { if (bReleaseNeeded) { - m_internalWaitObject.SafeWaitHandle.DangerousRelease(); + Debug.Assert(m_internalWaitObject != null, "Must be non-null for bReleaseNeeded to be true"); + m_internalWaitObject.SafeWaitHandle!.DangerousRelease(); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/2384 bReleaseNeeded = false; } // if result not true don't release/suppress here so finalizer can make another attempt @@ -141,7 +144,8 @@ namespace System.Threading WaitHandleCleanupNative(registeredWaitHandle); if (bReleaseNeeded) { - m_internalWaitObject.SafeWaitHandle.DangerousRelease(); + Debug.Assert(m_internalWaitObject != null, "Must be non-null for bReleaseNeeded to be true"); + m_internalWaitObject.SafeWaitHandle!.DangerousRelease(); // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/2384 bReleaseNeeded = false; } SetHandle(InvalidHandle); @@ -159,7 +163,7 @@ namespace System.Threading private static extern void WaitHandleCleanupNative(IntPtr handle); [MethodImplAttribute(MethodImplOptions.InternalCall)] - private static extern bool UnregisterWaitNative(IntPtr handle, SafeHandle waitObject); + private static extern bool UnregisterWaitNative(IntPtr handle, SafeHandle? waitObject); } public sealed class RegisteredWaitHandle : MarshalByRefObject @@ -181,9 +185,8 @@ namespace System.Threading internalRegisteredWait.SetWaitObject(waitObject); } - // This is the only public method on this class public bool Unregister( - WaitHandle waitObject // object to be notified when all callbacks to delegates have completed + WaitHandle? waitObject // object to be notified when all callbacks to delegates have completed ) { return internalRegisteredWait.Unregister(waitObject); @@ -231,7 +234,7 @@ namespace System.Threading private static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException WaitHandle waitObject, WaitOrTimerCallback callBack, - object state, + object? state, uint millisecondsTimeOutInterval, bool executeOnlyOnce, // NOTE: we do not allow other options that allow the callback to be queued as an APC bool compressStack diff --git a/src/System.Private.CoreLib/src/System/Threading/Timer.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Threading/Timer.CoreCLR.cs index 3d31a3f134..6e8306b74a 100644 --- a/src/System.Private.CoreLib/src/System/Threading/Timer.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Threading/Timer.CoreCLR.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.Win32; +#nullable enable using Microsoft.Win32.SafeHandles; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -61,7 +61,7 @@ namespace System.Threading private readonly int _id; // TimerQueues[_id] == this - private AppDomainTimerSafeHandle m_appDomainTimer; + private AppDomainTimerSafeHandle? m_appDomainTimer; private TimerQueue(int id) { diff --git a/src/System.Private.CoreLib/src/System/Threading/WaitHandle.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Threading/WaitHandle.CoreCLR.cs index 97b5c574e3..6bd426c624 100644 --- a/src/System.Private.CoreLib/src/System/Threading/WaitHandle.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Threading/WaitHandle.CoreCLR.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/System.Private.CoreLib/src/System/TypeLoadException.CoreCLR.cs b/src/System.Private.CoreLib/src/System/TypeLoadException.CoreCLR.cs index 729e119773..90f969ac9e 100644 --- a/src/System.Private.CoreLib/src/System/TypeLoadException.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/TypeLoadException.CoreCLR.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable using System.Runtime.InteropServices; using System.Runtime.CompilerServices; @@ -10,9 +11,9 @@ namespace System public partial class TypeLoadException : SystemException { // This is called from inside the EE. - private TypeLoadException(string className, - string assemblyName, - string messageArg, + private TypeLoadException(string? className, + string? assemblyName, + string? messageArg, int resourceId) : base(null) { @@ -40,7 +41,7 @@ namespace System if (_className == null) _className = SR.IO_UnknownFileName; - string format = null; + string? format = null; GetTypeLoadExceptionMessage(_resourceId, JitHelpers.GetStringHandleOnStack(ref format)); _message = string.Format(format, _className, _assemblyName, _messageArg); } diff --git a/src/System.Private.CoreLib/src/System/ValueType.cs b/src/System.Private.CoreLib/src/System/ValueType.cs index 516014f34e..bc834b1637 100644 --- a/src/System.Private.CoreLib/src/System/ValueType.cs +++ b/src/System.Private.CoreLib/src/System/ValueType.cs @@ -11,6 +11,7 @@ ** ===========================================================*/ +#nullable enable using System; using System.Reflection; using System.Runtime.CompilerServices; @@ -22,7 +23,7 @@ namespace System [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public abstract class ValueType { - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (null == obj) { @@ -88,7 +89,7 @@ namespace System [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern int GetHashCodeOfPtr(IntPtr ptr); - public override string ToString() + public override string? ToString() { return this.GetType().ToString(); } |