From 5ce35bf3d4456a81e22b6a74a03978a1a3abd75d Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Tue, 9 Apr 2019 12:10:28 -0400 Subject: [PATCH] Nullable: System.IO (#23732) * Nullable: System.IO Everything exception StreamReader, StreamWriter, BinaryReader, BinaryWriter, which are waiting for some changes in master to propagate over to the feature branch. * Address PR feedback --- .../System/IO/DisableMediaInsertionPrompt.cs | 1 + .../shared/System/IO/DriveInfoInternal.Unix.cs | 1 + .../shared/System/IO/DriveInfoInternal.Windows.cs | 3 +- .../shared/System/IO/EncodingCache.cs | 1 + .../shared/System/IO/Error.cs | 6 +- .../shared/System/IO/FileAccess.cs | 1 + .../shared/System/IO/FileMode.cs | 1 + .../shared/System/IO/FileOptions.cs | 1 + .../shared/System/IO/FileShare.cs | 1 + .../shared/System/IO/Path.Unix.cs | 7 +- .../shared/System/IO/Path.Windows.cs | 9 +- .../shared/System/IO/Path.cs | 17 ++-- .../shared/System/IO/PathHelper.Windows.cs | 3 +- .../shared/System/IO/PathInternal.Unix.cs | 3 +- .../shared/System/IO/PathInternal.Windows.cs | 7 +- .../shared/System/IO/PathInternal.cs | 1 + .../shared/System/IO/PersistedFiles.Names.Unix.cs | 1 + .../shared/System/IO/PersistedFiles.Unix.cs | 17 ++-- .../shared/System/IO/SeekOrigin.cs | 1 + .../shared/System/IO/TextReader.cs | 21 ++-- .../shared/System/IO/TextWriter.cs | 111 +++++++++++---------- .../shared/System/IO/UnmanagedMemoryAccessor.cs | 5 +- .../shared/System/ParamsArray.cs | 27 ++--- .../shared/System/Text/StringBuilder.cs | 2 +- 24 files changed, 132 insertions(+), 116 deletions(-) diff --git a/src/System.Private.CoreLib/shared/System/IO/DisableMediaInsertionPrompt.cs b/src/System.Private.CoreLib/shared/System/IO/DisableMediaInsertionPrompt.cs index a3a2d29..cfb4b66 100644 --- a/src/System.Private.CoreLib/shared/System/IO/DisableMediaInsertionPrompt.cs +++ b/src/System.Private.CoreLib/shared/System/IO/DisableMediaInsertionPrompt.cs @@ -2,6 +2,7 @@ // The .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 MS_IO_REDIST using System; diff --git a/src/System.Private.CoreLib/shared/System/IO/DriveInfoInternal.Unix.cs b/src/System.Private.CoreLib/shared/System/IO/DriveInfoInternal.Unix.cs index 78ef957..c4eba1c 100644 --- a/src/System.Private.CoreLib/shared/System/IO/DriveInfoInternal.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/IO/DriveInfoInternal.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; diff --git a/src/System.Private.CoreLib/shared/System/IO/DriveInfoInternal.Windows.cs b/src/System.Private.CoreLib/shared/System/IO/DriveInfoInternal.Windows.cs index 47dbcdd..6d6c2ea 100644 --- a/src/System.Private.CoreLib/shared/System/IO/DriveInfoInternal.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/IO/DriveInfoInternal.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.Text; @@ -51,7 +52,7 @@ namespace System.IO { Debug.Assert(driveName != null); - string name; + string? name; if (driveName.Length == 1) { diff --git a/src/System.Private.CoreLib/shared/System/IO/EncodingCache.cs b/src/System.Private.CoreLib/shared/System/IO/EncodingCache.cs index 53379bc..fb3795e 100644 --- a/src/System.Private.CoreLib/shared/System/IO/EncodingCache.cs +++ b/src/System.Private.CoreLib/shared/System/IO/EncodingCache.cs @@ -2,6 +2,7 @@ // The .NET Foundation 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; namespace System.IO diff --git a/src/System.Private.CoreLib/shared/System/IO/Error.cs b/src/System.Private.CoreLib/shared/System/IO/Error.cs index 1e319a0..db80954 100644 --- a/src/System.Private.CoreLib/shared/System/IO/Error.cs +++ b/src/System.Private.CoreLib/shared/System/IO/Error.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.Runtime.InteropServices; -using System.Text; -using System.Globalization; - +#nullable enable namespace System.IO { /// diff --git a/src/System.Private.CoreLib/shared/System/IO/FileAccess.cs b/src/System.Private.CoreLib/shared/System/IO/FileAccess.cs index 1b70bae..2fd7408 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileAccess.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileAccess.cs @@ -2,6 +2,7 @@ // The .NET Foundation 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.IO diff --git a/src/System.Private.CoreLib/shared/System/IO/FileMode.cs b/src/System.Private.CoreLib/shared/System/IO/FileMode.cs index 77f2fe6..39c74e5 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileMode.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileMode.cs @@ -2,6 +2,7 @@ // The .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 { // Contains constants for specifying how the OS should open a file. diff --git a/src/System.Private.CoreLib/shared/System/IO/FileOptions.cs b/src/System.Private.CoreLib/shared/System/IO/FileOptions.cs index ae8396a..b11b9bb 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileOptions.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileOptions.cs @@ -2,6 +2,7 @@ // The .NET Foundation 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/System/IO/FileShare.cs b/src/System.Private.CoreLib/shared/System/IO/FileShare.cs index e9b9b5e..12dc6e6 100644 --- a/src/System.Private.CoreLib/shared/System/IO/FileShare.cs +++ b/src/System.Private.CoreLib/shared/System/IO/FileShare.cs @@ -2,6 +2,7 @@ // The .NET Foundation 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.IO diff --git a/src/System.Private.CoreLib/shared/System/IO/Path.Unix.cs b/src/System.Private.CoreLib/shared/System/IO/Path.Unix.cs index ecf71e6..f8c93d6 100644 --- a/src/System.Private.CoreLib/shared/System/IO/Path.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/IO/Path.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.Text; @@ -77,7 +78,7 @@ namespace System.IO // Get the temp path from the TMPDIR environment variable. // If it's not set, just return the default path. // If it is, return it, ensuring it ends with a slash. - string path = Environment.GetEnvironmentVariable(TempEnvVar); + string? path = Environment.GetEnvironmentVariable(TempEnvVar); return string.IsNullOrEmpty(path) ? DefaultTempPath : PathInternal.IsDirectorySeparator(path[path.Length - 1]) ? path : @@ -103,7 +104,7 @@ namespace System.IO return Encoding.UTF8.GetString(name, 0, name.Length - 1); // trim off the trailing '\0' } - public static bool IsPathRooted(string path) + public static bool IsPathRooted(string? path) { if (path == null) return false; @@ -119,7 +120,7 @@ namespace System.IO /// /// Returns the path root or null if path is empty or null. /// - public static string GetPathRoot(string path) + public static string? GetPathRoot(string? path) { if (PathInternal.IsEffectivelyEmpty(path)) return null; diff --git a/src/System.Private.CoreLib/shared/System/IO/Path.Windows.cs b/src/System.Private.CoreLib/shared/System/IO/Path.Windows.cs index ddfd796..71a986e 100644 --- a/src/System.Private.CoreLib/shared/System/IO/Path.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/IO/Path.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.Text; @@ -83,7 +84,7 @@ namespace System.IO return basePath; int length = path.Length; - string combinedPath = null; + string? combinedPath = null; if ((length >= 1 && PathInternal.IsDirectorySeparator(path[0]))) { @@ -189,7 +190,7 @@ namespace System.IO // Tests if the given path contains a root. A path is considered rooted // if it starts with a backslash ("\") or a valid drive letter and a colon (":"). - public static bool IsPathRooted(string path) + public static bool IsPathRooted(string? path) { return path != null && IsPathRooted(path.AsSpan()); } @@ -210,13 +211,13 @@ namespace System.IO // and "\\server\share" (a UNC path for a given server and share name). // The resulting string is null if path is null. If the path is empty or // only contains whitespace characters an ArgumentException gets thrown. - public static string GetPathRoot(string path) + public static string? GetPathRoot(string? path) { if (PathInternal.IsEffectivelyEmpty(path.AsSpan())) return null; ReadOnlySpan result = GetPathRoot(path.AsSpan()); - if (path.Length == result.Length) + if (path!.Length == result.Length) return PathInternal.NormalizeDirectorySeparators(path); return PathInternal.NormalizeDirectorySeparators(result.ToString()); diff --git a/src/System.Private.CoreLib/shared/System/IO/Path.cs b/src/System.Private.CoreLib/shared/System/IO/Path.cs index 23da520..db491bf 100644 --- a/src/System.Private.CoreLib/shared/System/IO/Path.cs +++ b/src/System.Private.CoreLib/shared/System/IO/Path.cs @@ -2,6 +2,7 @@ // The .NET Foundation 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; @@ -45,7 +46,7 @@ namespace System.IO // returns null. If path does not contain a file extension, // the new file extension is appended to the path. If extension // is null, any existing extension is removed from path. - public static string ChangeExtension(string path, string extension) + public static string? ChangeExtension(string? path, string? extension) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { if (path == null) return null; @@ -98,7 +99,7 @@ namespace System.IO /// /// Directory separators are normalized in the returned string. /// - public static string GetDirectoryName(string path) + public static string? GetDirectoryName(string? path) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { if (path == null || PathInternal.IsEffectivelyEmpty(path.AsSpan())) return null; @@ -146,7 +147,7 @@ namespace System.IO /// The returned value is null if the given path is null or empty if the given path does not include an /// extension. /// - public static string GetExtension(string path) + public static string? GetExtension(string? path) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { if (path == null) return null; @@ -185,7 +186,7 @@ namespace System.IO /// the characters of path that follow the last separator in path. The resulting string is /// null if path is null. /// - public static string GetFileName(string path) + public static string? GetFileName(string? path) { if (path == null) return null; @@ -216,7 +217,7 @@ namespace System.IO return path; } - public static string GetFileNameWithoutExtension(string path) + public static string? GetFileNameWithoutExtension(string? path) // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 { if (path == null) return null; @@ -290,7 +291,7 @@ namespace System.IO /// Tests if a path's file name includes a file extension. A trailing period /// is not considered an extension. /// - public static bool HasExtension(string path) + public static bool HasExtension(string? path) { if (path != null) { @@ -433,12 +434,12 @@ namespace System.IO return JoinInternal(path1, path2, path3); } - public static string Join(string path1, string path2) + public static string Join(string? path1, string? path2) { return Join(path1.AsSpan(), path2.AsSpan()); } - public static string Join(string path1, string path2, string path3) + public static string Join(string? path1, string? path2, string? path3) { return Join(path1.AsSpan(), path2.AsSpan(), path3.AsSpan()); } diff --git a/src/System.Private.CoreLib/shared/System/IO/PathHelper.Windows.cs b/src/System.Private.CoreLib/shared/System/IO/PathHelper.Windows.cs index a30ead1..f494412 100644 --- a/src/System.Private.CoreLib/shared/System/IO/PathHelper.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/IO/PathHelper.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; @@ -126,7 +127,7 @@ namespace System.IO } } - internal static string TryExpandShortFileName(ref ValueStringBuilder outputBuilder, string originalPath) + internal static string TryExpandShortFileName(ref ValueStringBuilder outputBuilder, string? originalPath) { // We guarantee we'll expand short names for paths that only partially exist. As such, we need to find the part of the path that actually does exist. To // avoid allocating like crazy we'll create only one input array and modify the contents with embedded nulls. diff --git a/src/System.Private.CoreLib/shared/System/IO/PathInternal.Unix.cs b/src/System.Private.CoreLib/shared/System/IO/PathInternal.Unix.cs index fae309b..1888c85 100644 --- a/src/System.Private.CoreLib/shared/System/IO/PathInternal.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/IO/PathInternal.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; using System.Runtime.InteropServices; @@ -89,7 +90,7 @@ namespace System.IO /// For unix, this is empty or null. For Windows, this is empty, null, or /// just spaces ((char)32). /// - internal static bool IsEffectivelyEmpty(string path) + internal static bool IsEffectivelyEmpty(string? path) { return string.IsNullOrEmpty(path); } diff --git a/src/System.Private.CoreLib/shared/System/IO/PathInternal.Windows.cs b/src/System.Private.CoreLib/shared/System/IO/PathInternal.Windows.cs index 5e9e613..99aa021 100644 --- a/src/System.Private.CoreLib/shared/System/IO/PathInternal.Windows.cs +++ b/src/System.Private.CoreLib/shared/System/IO/PathInternal.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.Runtime.CompilerServices; using System.Text; @@ -70,7 +71,7 @@ namespace System.IO return ((value >= 'A' && value <= 'Z') || (value >= 'a' && value <= 'z')); } - internal static bool EndsWithPeriodOrSpace(string path) + internal static bool EndsWithPeriodOrSpace(string? path) { if (string.IsNullOrEmpty(path)) return false; @@ -86,7 +87,7 @@ namespace System.IO /// away from paths during normalization, but if we see such a path at this point it should be /// normalized and has retained the final characters. (Typically from one of the *Info classes) /// - internal static string EnsureExtendedPrefixIfNeeded(string path) + internal static string? EnsureExtendedPrefixIfNeeded(string? path) { if (path != null && (path.Length >= MaxShortPath || EndsWithPeriodOrSpace(path))) { @@ -103,7 +104,7 @@ namespace System.IO /// Adds the extended path prefix (\\?\) if not already a device path, IF the path is not relative, /// AND the path is more than 259 characters. (> MAX_PATH + null) /// - internal static string EnsureExtendedPrefixOverMaxPath(string path) + internal static string? EnsureExtendedPrefixOverMaxPath(string? path) { if (path != null && path.Length >= MaxShortPath) { diff --git a/src/System.Private.CoreLib/shared/System/IO/PathInternal.cs b/src/System.Private.CoreLib/shared/System/IO/PathInternal.cs index c6e1de4..549a2d1 100644 --- a/src/System.Private.CoreLib/shared/System/IO/PathInternal.cs +++ b/src/System.Private.CoreLib/shared/System/IO/PathInternal.cs @@ -2,6 +2,7 @@ // The .NET Foundation 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; diff --git a/src/System.Private.CoreLib/shared/System/IO/PersistedFiles.Names.Unix.cs b/src/System.Private.CoreLib/shared/System/IO/PersistedFiles.Names.Unix.cs index 8984f1a..03bfc02 100644 --- a/src/System.Private.CoreLib/shared/System/IO/PersistedFiles.Names.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/IO/PersistedFiles.Names.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.IO { internal static partial class PersistedFiles diff --git a/src/System.Private.CoreLib/shared/System/IO/PersistedFiles.Unix.cs b/src/System.Private.CoreLib/shared/System/IO/PersistedFiles.Unix.cs index d8064af..8dfa2f1 100644 --- a/src/System.Private.CoreLib/shared/System/IO/PersistedFiles.Unix.cs +++ b/src/System.Private.CoreLib/shared/System/IO/PersistedFiles.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; @@ -9,7 +10,7 @@ namespace System.IO { internal static partial class PersistedFiles { - private static string s_userProductDirectory; + private static string? s_userProductDirectory; /// /// Get the location of where to persist information for a particular aspect of the framework, @@ -24,7 +25,7 @@ namespace System.IO EnsureUserDirectories(); } - return Path.Combine(s_userProductDirectory, featureName); + return Path.Combine(s_userProductDirectory!, featureName); } /// @@ -41,7 +42,7 @@ namespace System.IO EnsureUserDirectories(); } - return Path.Combine(s_userProductDirectory, featureName, subFeatureName); + return Path.Combine(s_userProductDirectory!, featureName, subFeatureName); } /// @@ -60,12 +61,12 @@ namespace System.IO EnsureUserDirectories(); } - return Path.Combine(s_userProductDirectory, Path.Combine(featurePathParts)); + return Path.Combine(s_userProductDirectory!, Path.Combine(featurePathParts)); } private static void EnsureUserDirectories() { - string userHomeDirectory = GetHomeDirectory(); + string? userHomeDirectory = GetHomeDirectory(); if (string.IsNullOrEmpty(userHomeDirectory)) { @@ -80,11 +81,11 @@ namespace System.IO /// Gets the current user's home directory. /// The path to the home directory, or null if it could not be determined. - internal static string GetHomeDirectory() + internal static string? GetHomeDirectory() { // First try to get the user's home directory from the HOME environment variable. // This should work in most cases. - string userHomeDirectory = Environment.GetEnvironmentVariable("HOME"); + string? userHomeDirectory = Environment.GetEnvironmentVariable("HOME"); if (!string.IsNullOrEmpty(userHomeDirectory)) return userHomeDirectory; @@ -123,7 +124,7 @@ namespace System.IO /// The length of . /// The resulting path; null if the user didn't have an entry. /// true if the call was successful (path may still be null); false is a larger buffer is needed. - private static unsafe bool TryGetHomeDirectoryFromPasswd(byte* buf, int bufLen, out string path) + private static unsafe bool TryGetHomeDirectoryFromPasswd(byte* buf, int bufLen, out string? path) { // Call getpwuid_r to get the passwd struct Interop.Sys.Passwd passwd; diff --git a/src/System.Private.CoreLib/shared/System/IO/SeekOrigin.cs b/src/System.Private.CoreLib/shared/System/IO/SeekOrigin.cs index 3798a0c..e1da4d5 100644 --- a/src/System.Private.CoreLib/shared/System/IO/SeekOrigin.cs +++ b/src/System.Private.CoreLib/shared/System/IO/SeekOrigin.cs @@ -2,6 +2,7 @@ // The .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 { // Provides seek reference points. To seek to the end of a stream, diff --git a/src/System.Private.CoreLib/shared/System/IO/TextReader.cs b/src/System.Private.CoreLib/shared/System/IO/TextReader.cs index c1a9fd6..7a43f6e 100644 --- a/src/System.Private.CoreLib/shared/System/IO/TextReader.cs +++ b/src/System.Private.CoreLib/shared/System/IO/TextReader.cs @@ -2,6 +2,7 @@ // The .NET Foundation 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.Threading; using System.Threading.Tasks; @@ -178,7 +179,7 @@ namespace System.IO // contain the terminating carriage return and/or line feed. The returned // value is null if the end of the input stream has been reached. // - public virtual string ReadLine() + public virtual string? ReadLine() { StringBuilder sb = new StringBuilder(); while (true) @@ -205,11 +206,11 @@ namespace System.IO } #region Task based Async APIs - public virtual Task ReadLineAsync() + public virtual Task ReadLineAsync() { - return Task.Factory.StartNew(state => + return Task.Factory.StartNew(state => { - return ((TextReader)state).ReadLine(); + return ((TextReader)state!).ReadLine(); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 }, this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } @@ -256,7 +257,7 @@ namespace System.IO ReadAsync(array.Array, array.Offset, array.Count) : Task.Factory.StartNew(state => { - var t = (Tuple>)state; + var t = (Tuple>)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 return t.Item1.Read(t.Item2.Span); }, Tuple.Create(this, buffer), cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default)); @@ -265,7 +266,7 @@ namespace System.IO var tuple = new Tuple>(this, buffer); return new ValueTask(Task.Factory.StartNew(state => { - var t = (Tuple>)state; + var t = (Tuple>)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 return t.Item1.Read(t.Item2.Span); }, tuple, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default)); @@ -294,7 +295,7 @@ namespace System.IO ReadBlockAsync(array.Array, array.Offset, array.Count) : Task.Factory.StartNew(state => { - var t = (Tuple>)state; + var t = (Tuple>)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 return t.Item1.ReadBlock(t.Item2.Span); }, Tuple.Create(this, buffer), cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default)); @@ -320,7 +321,7 @@ namespace System.IO return 0; } - public override string ReadLine() + public override string? ReadLine() { return null; } @@ -367,7 +368,7 @@ namespace System.IO public override int ReadBlock(char[] buffer, int index, int count) => _in.ReadBlock(buffer, index, count); [MethodImpl(MethodImplOptions.Synchronized)] - public override string ReadLine() => _in.ReadLine(); + public override string? ReadLine() => _in.ReadLine(); [MethodImpl(MethodImplOptions.Synchronized)] public override string ReadToEnd() => _in.ReadToEnd(); @@ -377,7 +378,7 @@ namespace System.IO // [MethodImpl(MethodImplOptions.Synchronized)] - public override Task ReadLineAsync() => Task.FromResult(ReadLine()); + public override Task ReadLineAsync() => Task.FromResult(ReadLine()); [MethodImpl(MethodImplOptions.Synchronized)] public override Task ReadToEndAsync() => Task.FromResult(ReadToEnd()); diff --git a/src/System.Private.CoreLib/shared/System/IO/TextWriter.cs b/src/System.Private.CoreLib/shared/System/IO/TextWriter.cs index baf53b4..d66ee43 100644 --- a/src/System.Private.CoreLib/shared/System/IO/TextWriter.cs +++ b/src/System.Private.CoreLib/shared/System/IO/TextWriter.cs @@ -2,6 +2,7 @@ // The .NET Foundation 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.Threading; using System.Globalization; @@ -36,14 +37,14 @@ namespace System.IO private string CoreNewLineStr = Environment.NewLine; // Can be null - if so, ask for the Thread's CurrentCulture every time. - private IFormatProvider _internalFormatProvider; + private IFormatProvider? _internalFormatProvider; protected TextWriter() { _internalFormatProvider = null; // Ask for CurrentCulture all the time. } - protected TextWriter(IFormatProvider formatProvider) + protected TextWriter(IFormatProvider? formatProvider) { _internalFormatProvider = formatProvider; } @@ -117,7 +118,7 @@ namespace System.IO /// the TextWriter to be readable by a TextReader, only one of the following line /// terminator strings should be used: "\r", "\n", or "\r\n". /// - public virtual string NewLine + public virtual string? NewLine // TODO-NULLABLE: https://github.com/dotnet/csharplang/issues/2384 { get { return CoreNewLineStr; } set @@ -268,7 +269,7 @@ namespace System.IO // Writes a string to the text stream. If the given string is null, nothing // is written to the text stream. // - public virtual void Write(string value) + public virtual void Write(string? value) { if (value != null) { @@ -282,7 +283,7 @@ namespace System.IO // string representation, and the resulting string is then written to the // output stream. // - public virtual void Write(object value) + public virtual void Write(object? value) { if (value != null) { @@ -300,7 +301,7 @@ namespace System.IO /// StringBuilder.GetChunks() method to avoid creating the intermediate string /// /// The string (as a StringBuilder) to write to the stream - public virtual void Write(StringBuilder value) + public virtual void Write(StringBuilder? value) { if (value != null) { @@ -312,7 +313,7 @@ namespace System.IO // Writes out a formatted string. Uses the same semantics as // string.Format. // - public virtual void Write(string format, object arg0) + public virtual void Write(string format, object? arg0) { Write(string.Format(FormatProvider, format, arg0)); } @@ -320,7 +321,7 @@ namespace System.IO // Writes out a formatted string. Uses the same semantics as // string.Format. // - public virtual void Write(string format, object arg0, object arg1) + public virtual void Write(string format, object? arg0, object? arg1) { Write(string.Format(FormatProvider, format, arg0, arg1)); } @@ -328,7 +329,7 @@ namespace System.IO // Writes out a formatted string. Uses the same semantics as // string.Format. // - public virtual void Write(string format, object arg0, object arg1, object arg2) + public virtual void Write(string format, object? arg0, object? arg1, object? arg2) { Write(string.Format(FormatProvider, format, arg0, arg1, arg2)); } @@ -336,7 +337,7 @@ namespace System.IO // Writes out a formatted string. Uses the same semantics as // string.Format. // - public virtual void Write(string format, params object[] arg) + public virtual void Write(string format, params object?[] arg) { Write(string.Format(FormatProvider, format, arg)); } @@ -464,7 +465,7 @@ namespace System.IO // Writes a string followed by a line terminator to the text stream. // - public virtual void WriteLine(string value) + public virtual void WriteLine(string? value) { if (value != null) { @@ -477,7 +478,7 @@ namespace System.IO /// Equivalent to WriteLine(stringBuilder.ToString()) however it uses the /// StringBuilder.GetChunks() method to avoid creating the intermediate string /// - public virtual void WriteLine(StringBuilder value) + public virtual void WriteLine(StringBuilder? value) { Write(value); WriteLine(); @@ -486,7 +487,7 @@ namespace System.IO // Writes the text representation of an object followed by a line // terminator to the text stream. // - public virtual void WriteLine(object value) + public virtual void WriteLine(object? value) { if (value == null) { @@ -510,7 +511,7 @@ namespace System.IO // Writes out a formatted string and a new line. Uses the same // semantics as string.Format. // - public virtual void WriteLine(string format, object arg0) + public virtual void WriteLine(string format, object? arg0) { WriteLine(string.Format(FormatProvider, format, arg0)); } @@ -518,7 +519,7 @@ namespace System.IO // Writes out a formatted string and a new line. Uses the same // semantics as string.Format. // - public virtual void WriteLine(string format, object arg0, object arg1) + public virtual void WriteLine(string format, object? arg0, object? arg1) { WriteLine(string.Format(FormatProvider, format, arg0, arg1)); } @@ -526,7 +527,7 @@ namespace System.IO // Writes out a formatted string and a new line. Uses the same // semantics as string.Format. // - public virtual void WriteLine(string format, object arg0, object arg1, object arg2) + public virtual void WriteLine(string format, object? arg0, object? arg1, object? arg2) { WriteLine(string.Format(FormatProvider, format, arg0, arg1, arg2)); } @@ -534,7 +535,7 @@ namespace System.IO // Writes out a formatted string and a new line. Uses the same // semantics as string.Format. // - public virtual void WriteLine(string format, params object[] arg) + public virtual void WriteLine(string format, params object?[] arg) { WriteLine(string.Format(FormatProvider, format, arg)); } @@ -545,18 +546,18 @@ namespace System.IO var tuple = new Tuple(this, value); return Task.Factory.StartNew(state => { - var t = (Tuple)state; + var t = (Tuple)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 t.Item1.Write(t.Item2); }, tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } - public virtual Task WriteAsync(string value) + public virtual Task WriteAsync(string? value) { - var tuple = new Tuple(this, value); + var tuple = new Tuple(this, value); return Task.Factory.StartNew(state => { - var t = (Tuple)state; + var t = (Tuple)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 t.Item1.Write(t.Item2); }, tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); @@ -567,7 +568,7 @@ namespace System.IO /// StringBuilder.GetChunks() method to avoid creating the intermediate string /// /// The string (as a StringBuilder) to write to the stream - public virtual Task WriteAsync(StringBuilder value, CancellationToken cancellationToken = default) + public virtual Task WriteAsync(StringBuilder? value, CancellationToken cancellationToken = default) { return cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) : @@ -598,7 +599,7 @@ namespace System.IO var tuple = new Tuple(this, buffer, index, count); return Task.Factory.StartNew(state => { - var t = (Tuple)state; + var t = (Tuple)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 t.Item1.Write(t.Item2, t.Item3, t.Item4); }, tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); @@ -610,7 +611,7 @@ namespace System.IO WriteAsync(array.Array, array.Offset, array.Count) : Task.Factory.StartNew(state => { - var t = (Tuple>)state; + var t = (Tuple>)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 t.Item1.Write(t.Item2.Span); }, Tuple.Create(this, buffer), cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); @@ -619,18 +620,18 @@ namespace System.IO var tuple = new Tuple(this, value); return Task.Factory.StartNew(state => { - var t = (Tuple)state; + var t = (Tuple)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 t.Item1.WriteLine(t.Item2); }, tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } - public virtual Task WriteLineAsync(string value) + public virtual Task WriteLineAsync(string? value) { - var tuple = new Tuple(this, value); + var tuple = new Tuple(this, value); return Task.Factory.StartNew(state => { - var t = (Tuple)state; + var t = (Tuple)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 t.Item1.WriteLine(t.Item2); }, tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); @@ -641,7 +642,7 @@ namespace System.IO /// StringBuilder.GetChunks() method to avoid creating the intermediate string /// /// The string (as a StringBuilder) to write to the stream - public virtual Task WriteLineAsync(StringBuilder value, CancellationToken cancellationToken = default) + public virtual Task WriteLineAsync(StringBuilder? value, CancellationToken cancellationToken = default) { return cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) : @@ -673,7 +674,7 @@ namespace System.IO var tuple = new Tuple(this, buffer, index, count); return Task.Factory.StartNew(state => { - var t = (Tuple)state; + var t = (Tuple)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 t.Item1.WriteLine(t.Item2, t.Item3, t.Item4); }, tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); @@ -685,7 +686,7 @@ namespace System.IO WriteLineAsync(array.Array, array.Offset, array.Count) : Task.Factory.StartNew(state => { - var t = (Tuple>)state; + var t = (Tuple>)state!; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 t.Item1.WriteLine(t.Item2.Span); }, Tuple.Create(this, buffer), cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); @@ -698,7 +699,7 @@ namespace System.IO { return Task.Factory.StartNew(state => { - ((TextWriter)state).Flush(); + ((TextWriter)state!).Flush(); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 }, this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } @@ -722,7 +723,7 @@ namespace System.IO { } - public override void Write(string value) + public override void Write(string? value) { } @@ -732,11 +733,11 @@ namespace System.IO } // Not strictly necessary, but for perf reasons - public override void WriteLine(string value) + public override void WriteLine(string? value) { } - public override void WriteLine(object value) + public override void WriteLine(object? value) { } @@ -762,11 +763,11 @@ namespace System.IO _out = t; } - public override Encoding Encoding => _out.Encoding; + public override Encoding Encoding => _out.Encoding; public override IFormatProvider FormatProvider => _out.FormatProvider; - public override string NewLine + public override string? NewLine { [MethodImpl(MethodImplOptions.Synchronized)] get { return _out.NewLine; } @@ -825,25 +826,25 @@ namespace System.IO public override void Write(decimal value) => _out.Write(value); [MethodImpl(MethodImplOptions.Synchronized)] - public override void Write(string value) => _out.Write(value); + public override void Write(string? value) => _out.Write(value); [MethodImpl(MethodImplOptions.Synchronized)] - public override void Write(StringBuilder value) => _out.Write(value); + public override void Write(StringBuilder? value) => _out.Write(value); [MethodImpl(MethodImplOptions.Synchronized)] - public override void Write(object value) => _out.Write(value); + public override void Write(object? value) => _out.Write(value); [MethodImpl(MethodImplOptions.Synchronized)] - public override void Write(string format, object arg0) => _out.Write(format, arg0); + public override void Write(string format, object? arg0) => _out.Write(format, arg0); [MethodImpl(MethodImplOptions.Synchronized)] - public override void Write(string format, object arg0, object arg1) => _out.Write(format, arg0, arg1); + public override void Write(string format, object? arg0, object? arg1) => _out.Write(format, arg0, arg1); [MethodImpl(MethodImplOptions.Synchronized)] - public override void Write(string format, object arg0, object arg1, object arg2) => _out.Write(format, arg0, arg1, arg2); + public override void Write(string format, object? arg0, object? arg1, object? arg2) => _out.Write(format, arg0, arg1, arg2); [MethodImpl(MethodImplOptions.Synchronized)] - public override void Write(string format, object[] arg) => _out.Write(format, arg); + public override void Write(string format, object?[] arg) => _out.Write(format, arg); [MethodImpl(MethodImplOptions.Synchronized)] public override void WriteLine() => _out.WriteLine(); @@ -885,25 +886,25 @@ namespace System.IO public override void WriteLine(double value) => _out.WriteLine(value); [MethodImpl(MethodImplOptions.Synchronized)] - public override void WriteLine(string value) => _out.WriteLine(value); + public override void WriteLine(string? value) => _out.WriteLine(value); [MethodImpl(MethodImplOptions.Synchronized)] - public override void WriteLine(StringBuilder value) => _out.WriteLine(value); + public override void WriteLine(StringBuilder? value) => _out.WriteLine(value); [MethodImpl(MethodImplOptions.Synchronized)] - public override void WriteLine(object value) => _out.WriteLine(value); + public override void WriteLine(object? value) => _out.WriteLine(value); [MethodImpl(MethodImplOptions.Synchronized)] - public override void WriteLine(string format, object arg0) => _out.WriteLine(format, arg0); + public override void WriteLine(string format, object? arg0) => _out.WriteLine(format, arg0); [MethodImpl(MethodImplOptions.Synchronized)] - public override void WriteLine(string format, object arg0, object arg1) => _out.WriteLine(format, arg0, arg1); + public override void WriteLine(string format, object? arg0, object? arg1) => _out.WriteLine(format, arg0, arg1); [MethodImpl(MethodImplOptions.Synchronized)] - public override void WriteLine(string format, object arg0, object arg1, object arg2) => _out.WriteLine(format, arg0, arg1, arg2); + public override void WriteLine(string format, object? arg0, object? arg1, object? arg2) => _out.WriteLine(format, arg0, arg1, arg2); [MethodImpl(MethodImplOptions.Synchronized)] - public override void WriteLine(string format, object[] arg) => _out.WriteLine(format, arg); + public override void WriteLine(string format, object?[] arg) => _out.WriteLine(format, arg); // // On SyncTextWriter all APIs should run synchronously, even the async ones. @@ -924,14 +925,14 @@ namespace System.IO } [MethodImpl(MethodImplOptions.Synchronized)] - public override Task WriteAsync(string value) + public override Task WriteAsync(string? value) { Write(value); return Task.CompletedTask; } [MethodImpl(MethodImplOptions.Synchronized)] - public override Task WriteAsync(StringBuilder value, CancellationToken cancellationToken = default) + public override Task WriteAsync(StringBuilder? value, CancellationToken cancellationToken = default) { if (cancellationToken.IsCancellationRequested) { @@ -988,14 +989,14 @@ namespace System.IO } [MethodImpl(MethodImplOptions.Synchronized)] - public override Task WriteLineAsync(string value) + public override Task WriteLineAsync(string? value) { WriteLine(value); return Task.CompletedTask; } [MethodImpl(MethodImplOptions.Synchronized)] - public override Task WriteLineAsync(StringBuilder value, CancellationToken cancellationToken = default) + public override Task WriteLineAsync(StringBuilder? value, CancellationToken cancellationToken = default) { if (cancellationToken.IsCancellationRequested) { diff --git a/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryAccessor.cs b/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryAccessor.cs index 1247ad6..4e66b7c 100644 --- a/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryAccessor.cs +++ b/src/System.Private.CoreLib/shared/System/IO/UnmanagedMemoryAccessor.cs @@ -13,8 +13,7 @@ ** ===========================================================*/ -using System.Diagnostics; -using System.Runtime.CompilerServices; +#nullable enable using System.Runtime.InteropServices; using Internal.Runtime.CompilerServices; @@ -25,7 +24,7 @@ namespace System.IO /// this gives better throughput; benchmarks showed about 12-15% better. public class UnmanagedMemoryAccessor : IDisposable { - private SafeBuffer _buffer; + private SafeBuffer _buffer = null!; // initialized in helper called by ctor private long _offset; private long _capacity; private FileAccess _access; diff --git a/src/System.Private.CoreLib/shared/System/ParamsArray.cs b/src/System.Private.CoreLib/shared/System/ParamsArray.cs index 043ee67..91b2bd1 100644 --- a/src/System.Private.CoreLib/shared/System/ParamsArray.cs +++ b/src/System.Private.CoreLib/shared/System/ParamsArray.cs @@ -2,6 +2,7 @@ // The .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 { internal readonly struct ParamsArray @@ -9,19 +10,19 @@ namespace System // Sentinel fixed-length arrays eliminate the need for a "count" field keeping this // struct down to just 4 fields. These are only used for their "Length" property, // that is, their elements are never set or referenced. - private static readonly object[] s_oneArgArray = new object[1]; - private static readonly object[] s_twoArgArray = new object[2]; - private static readonly object[] s_threeArgArray = new object[3]; + private static readonly object?[] s_oneArgArray = new object?[1]; + private static readonly object?[] s_twoArgArray = new object?[2]; + private static readonly object?[] s_threeArgArray = new object?[3]; - private readonly object _arg0; - private readonly object _arg1; - private readonly object _arg2; + private readonly object? _arg0; + private readonly object? _arg1; + private readonly object? _arg2; // After construction, the first three elements of this array will never be accessed // because the indexer will retrieve those values from arg0, arg1, and arg2. - private readonly object[] _args; + private readonly object?[] _args; - public ParamsArray(object arg0) + public ParamsArray(object? arg0) { _arg0 = arg0; _arg1 = null; @@ -31,7 +32,7 @@ namespace System _args = s_oneArgArray; } - public ParamsArray(object arg0, object arg1) + public ParamsArray(object? arg0, object? arg1) { _arg0 = arg0; _arg1 = arg1; @@ -41,7 +42,7 @@ namespace System _args = s_twoArgArray; } - public ParamsArray(object arg0, object arg1, object arg2) + public ParamsArray(object? arg0, object? arg1, object? arg2) { _arg0 = arg0; _arg1 = arg1; @@ -51,7 +52,7 @@ namespace System _args = s_threeArgArray; } - public ParamsArray(object[] args) + public ParamsArray(object?[] args) { int len = args.Length; _arg0 = len > 0 ? args[0] : null; @@ -65,12 +66,12 @@ namespace System get { return _args.Length; } } - public object this[int index] + public object? this[int index] { get { return index == 0 ? _arg0 : GetAtSlow(index); } } - private object GetAtSlow(int index) + private object? GetAtSlow(int index) { if (index == 1) return _arg1; diff --git a/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs b/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs index e05e966..41b16cf 100644 --- a/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs +++ b/src/System.Private.CoreLib/shared/System/Text/StringBuilder.cs @@ -1654,7 +1654,7 @@ namespace System.Text // // Start of parsing of optional formatting parameter. // - object arg = args[index]; + object? arg = args[index]; string? itemFormat = null; ReadOnlySpan itemFormatSpan = default; // used if itemFormat is null // Is current character a colon? which indicates start of formatting parameter. -- 2.7.4