Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Span.TryWrite, StringBuilder.Append, and String.Create interpolated strings support #51653

Merged
merged 4 commits into from
Jul 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ internal static partial class procfs
{
private const string MapsFileName = "/maps";

private static string GetMapsFilePathForProcess(int pid) =>
RootPath + pid.ToString(CultureInfo.InvariantCulture) + MapsFileName;
private static string GetMapsFilePathForProcess(int pid) => string.Create(null, stackalloc char[256], $"{RootPath}{(uint)pid}{MapsFileName}");

internal static ProcessModuleCollection? ParseMapsModules(int pid)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ internal struct ParsedStatus
internal ulong VmPeak;
}

internal static string GetStatusFilePathForProcess(int pid)
{
return RootPath + pid.ToString(CultureInfo.InvariantCulture) + StatusFileName;
}
internal static string GetStatusFilePathForProcess(int pid) => string.Create(null, stackalloc char[256], $"{RootPath}{(uint)pid}{StatusFileName}");

internal static bool TryReadStatusFile(int pid, out ParsedStatus result)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,41 +76,17 @@ internal struct ParsedStat
//internal long cguest_time;
}

internal static string GetExeFilePathForProcess(int pid)
{
return RootPath + pid.ToString(CultureInfo.InvariantCulture) + ExeFileName;
}
internal static string GetExeFilePathForProcess(int pid) => string.Create(null, stackalloc char[256], $"{RootPath}{(uint)pid}{ExeFileName}");

internal static string GetCmdLinePathForProcess(int pid)
{
return RootPath + pid.ToString(CultureInfo.InvariantCulture) + CmdLineFileName;
}
internal static string GetCmdLinePathForProcess(int pid) => string.Create(null, stackalloc char[256], $"{RootPath}{(uint)pid}{CmdLineFileName}");

internal static string GetStatFilePathForProcess(int pid)
{
return RootPath + pid.ToString(CultureInfo.InvariantCulture) + StatFileName;
}
internal static string GetStatFilePathForProcess(int pid) => string.Create(null, stackalloc char[256], $"{RootPath}{(uint)pid}{StatFileName}");

internal static string GetTaskDirectoryPathForProcess(int pid)
{
return RootPath + pid.ToString(CultureInfo.InvariantCulture) + TaskDirectoryName;
}
internal static string GetTaskDirectoryPathForProcess(int pid) => string.Create(null, stackalloc char[256], $"{RootPath}{(uint)pid}{TaskDirectoryName}");

internal static string GetFileDescriptorDirectoryPathForProcess(int pid)
{
return RootPath + pid.ToString(CultureInfo.InvariantCulture) + FileDescriptorDirectoryName;
}
internal static string GetFileDescriptorDirectoryPathForProcess(int pid) => string.Create(null, stackalloc char[256], $"{RootPath}{(uint)pid}{FileDescriptorDirectoryName}");

private static string GetStatFilePathForThread(int pid, int tid)
{
// Perf note: Calling GetTaskDirectoryPathForProcess will allocate a string,
// which we then use in another Concat call to produce another string. The straightforward alternative,
// though, since we have five input strings, is to use the string.Concat overload that takes a params array.
// This results in allocating not only the params array but also a defensive copy inside of Concat,
// which means allocating two five-element arrays. This two-string approach will result not only in fewer
// allocations, but also typically in less memory allocated, and it's a bit more maintainable.
return GetTaskDirectoryPathForProcess(pid) + tid.ToString(CultureInfo.InvariantCulture) + StatFileName;
}
private static string GetStatFilePathForThread(int pid, int tid) => string.Create(null, stackalloc char[256], $"{RootPath}{(uint)pid}{TaskDirectoryName}{(uint)tid}{StatFileName}");

internal static bool TryReadStatFile(int pid, out ParsedStat result)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal struct GssBuffer : IDisposable
internal int Copy(byte[] destination, int offset)
{
Debug.Assert(destination != null, "target destination cannot be null");
Debug.Assert((offset >= 0 && offset < destination.Length) || destination.Length == 0, "invalid offset " + offset);
Debug.Assert((offset >= 0 && offset < destination.Length) || destination.Length == 0, $"invalid offset {offset}");

if (_data == IntPtr.Zero || _length == 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ internal static int Encrypt(SafeSslHandle context, ReadOnlySpan<byte> input, ref
{
#if DEBUG
ulong assertNoError = Crypto.ErrPeekError();
Debug.Assert(assertNoError == 0, "OpenSsl error queue is not empty, run: 'openssl errstr " + assertNoError.ToString("X") + "' for original error.");
Debug.Assert(assertNoError == 0, $"OpenSsl error queue is not empty, run: 'openssl errstr {assertNoError:X}' for original error.");
#endif
errorCode = Ssl.SslErrorCode.SSL_ERROR_NONE;

Expand Down Expand Up @@ -349,7 +349,7 @@ internal static int Decrypt(SafeSslHandle context, Span<byte> buffer, out Ssl.Ss
{
#if DEBUG
ulong assertNoError = Crypto.ErrPeekError();
Debug.Assert(assertNoError == 0, "OpenSsl error queue is not empty, run: 'openssl errstr " + assertNoError.ToString("X") + "' for original error.");
Debug.Assert(assertNoError == 0, $"OpenSsl error queue is not empty, run: 'openssl errstr {assertNoError:X}' for original error.");
#endif
errorCode = Ssl.SslErrorCode.SSL_ERROR_NONE;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,7 @@ internal unsafe SecurityPackageInfoClass(SafeHandle safeHandle, int index)
if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, this.ToString());
}

public override string ToString()
{
return "Capabilities:" + string.Format(CultureInfo.InvariantCulture, "0x{0:x}", Capabilities)
+ " Version:" + Version.ToString(NumberFormatInfo.InvariantInfo)
+ " RPCID:" + RPCID.ToString(NumberFormatInfo.InvariantInfo)
+ " MaxToken:" + MaxToken.ToString(NumberFormatInfo.InvariantInfo)
+ " Name:" + ((Name == null) ? "(null)" : Name)
+ " Comment:" + ((Comment == null) ? "(null)" : Comment);
}
public override string ToString() =>
$"Capabilities:0x{Capabilities:x} Version:{Version} RPCID:{RPCID} MaxToken:{MaxToken} Name:{Name ?? "(null)"} Comment: {Comment ?? "(null)"}";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ public string BaseType

string returnType = _baseType;
return _needsFixup && TypeArguments.Count > 0 ?
returnType + '`' + TypeArguments.Count.ToString(CultureInfo.InvariantCulture) :
$"{returnType}`{(uint)TypeArguments.Count}" :
stephentoub marked this conversation as resolved.
Show resolved Hide resolved
returnType;
}
set
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ private static string CreateLogMessage(TraceEventType eventType, CompositionTrac
StringBuilder messageBuilder = new StringBuilder();

// Format taken from TraceListener.TraceEvent in .NET Framework
messageBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0} {1}: {2} : ",
s_sourceName, eventType.ToString(), (int)traceId);
messageBuilder.Append($"{s_sourceName} {eventType}: {(int)traceId} : ");

if (arguments == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,11 +525,11 @@ private static void ParseComparison(Dictionary<string, string?> parsetable, stri
}
}
}
Debug.Assert(isEquivalent, "ParseInternal code vs regex message mismatch: <" + msg1 + "> <" + msg2 + ">");
Debug.Assert(isEquivalent, $"ParseInternal code vs regex message mismatch: <{msg1}> <{msg2}>");
}
else
{
Debug.Fail("ParseInternal code vs regex throw mismatch " + f.Message);
Debug.Fail($"ParseInternal code vs regex throw mismatch {f.Message}");
}
e = null;
}
Expand Down
4 changes: 1 addition & 3 deletions src/libraries/Common/src/System/Drawing/ColorTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,7 @@ public static string ToHtml(Color c)
}
else
{
colorString = "#" + c.R.ToString("X2", null) +
c.G.ToString("X2", null) +
c.B.ToString("X2", null);
colorString = $"#{c.R:X2}{c.G:X2}{c.B:X2}";
}

return colorString;
Expand Down
2 changes: 1 addition & 1 deletion src/libraries/Common/src/System/IO/RowConfigReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private bool TryFindNextKeyOccurrence(string key, int startIndex, out int keyInd
}
// Check If the match is at the beginning of the string, or is preceded by a newline.
else if (keyIndex == 0
|| (keyIndex >= Environment.NewLine.Length && _buffer.Substring(keyIndex - Environment.NewLine.Length, Environment.NewLine.Length) == Environment.NewLine))
|| (keyIndex >= Environment.NewLine.Length && _buffer.AsSpan(keyIndex - Environment.NewLine.Length, Environment.NewLine.Length).SequenceEqual(Environment.NewLine)))
{
// Check if the match is followed by whitespace, meaning it is not part of a larger word.
if (HasFollowingWhitespace(keyIndex, key.Length))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ internal static int VerifySignature(SafeDeleteContext securityContext, byte[] bu
// throw if error
if (errorCode != 0)
{
NetEventSource.Info($"VerifySignature threw error: {errorCode.ToString("x", NumberFormatInfo.InvariantInfo)}");
NetEventSource.Info($"VerifySignature threw error: {errorCode:x}");
throw new Win32Exception(errorCode);
}

Expand Down Expand Up @@ -256,7 +256,7 @@ internal static int MakeSignature(SafeDeleteContext securityContext, byte[] buff
// throw if error
if (errorCode != 0)
{
NetEventSource.Info($"MakeSignature threw error: {errorCode.ToString("x", NumberFormatInfo.InvariantInfo)}");
NetEventSource.Info($"MakeSignature threw error: {errorCode:x}");
throw new Win32Exception(errorCode);
}

Expand Down
24 changes: 12 additions & 12 deletions src/libraries/Common/tests/StaticTestGenerator/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -710,12 +710,12 @@ private static string EncodeLiteral(object? literal, Type? expectedType)

if (literal is IntPtr ptr)
{
return $"new IntPtr(0x{((long)ptr).ToString("X")})";
return $"new IntPtr(0x{(long)ptr:X})";
}

if (literal is UIntPtr uptr)
{
return $"new UIntPtr(0x{((ulong)uptr).ToString("X")})";
return $"new UIntPtr(0x{(ulong)uptr:X})";
}

string? result = null;
Expand All @@ -732,34 +732,34 @@ private static string EncodeLiteral(object? literal, Type? expectedType)
result = ((bool)literal).ToString().ToLowerInvariant();
break;
case TypeCode.Char:
result = $"'\\u{((int)(char)literal).ToString("X4")}'";
result = $"'\\u{(int)(char)literal:X4}'";
break;
case TypeCode.SByte:
result = $"(sbyte)({literal.ToString()})";
result = $"(sbyte)({literal})";
break;
case TypeCode.Byte:
result = $"(byte){literal.ToString()}";
result = $"(byte){literal}";
break;
case TypeCode.Int16:
result = $"(short)({literal.ToString()})";
result = $"(short)({literal})";
break;
case TypeCode.UInt16:
result = $"(ushort){literal.ToString()}";
result = $"(ushort){literal}";
break;
case TypeCode.Int32:
result = $"({literal.ToString()})";
result = $"({literal})";
break;
case TypeCode.UInt32:
result = $"{literal.ToString()}U";
result = $"{literal}U";
break;
case TypeCode.Int64:
result = $"({literal.ToString()}L)";
result = $"({literal}L)";
break;
case TypeCode.UInt64:
result = $"{literal.ToString()}UL";
result = $"{literal}UL";
break;
case TypeCode.Decimal:
result = $"({literal.ToString()}M)";
result = $"({literal}M)";
break;
case TypeCode.Single:
result =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<EnableDefaultItems>false</EnableDefaultItems>
<LangVersion>preview</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
Expand All @@ -21,4 +21,4 @@
<PackageReference Include="xunit.core" Version="2.4.1" />
<PackageReference Include="xunit.runner.utility" Version="2.4.1" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ await server.AcceptConnectionAsync(async connection =>
{
int bytesRemaining = expectedData.Length - bytesSent;
int bytesToSend = rand.Next(1, Math.Min(bytesRemaining, maxChunkSize + 1));
await connection.WriteStringAsync(bytesToSend.ToString("X") + lineEnding);
await connection.WriteStringAsync($"{bytesToSend:X}{lineEnding}");
await connection.Stream.WriteAsync(new Memory<byte>(expectedData, bytesSent, bytesToSend));
await connection.WriteStringAsync(lineEnding);
bytesSent += bytesToSend;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ internal static string ByteArrayToHex(this ReadOnlySpan<byte> bytes)

for (int i = 0; i < bytes.Length; i++)
{
builder.Append(bytes[i].ToString("X2"));
builder.Append($"{bytes[i]:X2}");
}

return builder.ToString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,14 @@ public void WriteDocType(string name, string sysid, string pubid, string subset)
if (pubid == null)
{
if (sysid != null)
dt.Append(" SYSTEM " + sysid);
dt.Append($" SYSTEM {sysid}");
}
else
{
dt.Append(" PUBLIC " + pubid);
dt.Append($" PUBLIC {pubid}");
if (sysid != null)
{
dt.Append(" " + sysid);
dt.Append($" {sysid}");
}
}

Expand Down Expand Up @@ -298,23 +298,23 @@ public void PutByte()
/// </summary>
public void PutCData()
{
_q.Append("<![CDATA[" + CDATA + _cCount++ + "]]>");
_q.Append($"<![CDATA[{CDATA}{_cCount++}]]>");
}

/// <summary>
/// Writes out a PI Node.
/// </summary>
public void PutPI()
{
_q.Append("<?" + PI + _pCount++ + "?>");
_q.Append($"<?{PI}{_pCount++}?>");
}

/// <summary>
/// Writes out a Comment Node.
/// </summary>
public void PutComment()
{
_q.Append("<!--" + COMMENT + _mCount++ + " -->");
_q.Append($"<!--{COMMENT}{_mCount++} -->");
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1594,7 +1594,7 @@ public override void WriteTo(XmlWriter w)
w.WriteString(Value);
break;
default:
Debug.Assert(false, "Wrong type for text-like node : " + this._nodetype.ToString());
Debug.Assert(false, $"Wrong type for text-like node : {this._nodetype}");
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ private static Dictionary<int, string> ProcessDerivedNameFile()
string baseName = value.PropName[..^1];
for (int i = value.FirstCodePoint; i <= value.LastCodePoint /* inclusive */; i++)
{
dict.Add(i, baseName + i.ToString("X4", CultureInfo.InvariantCulture));
dict.Add(i, $"{baseName}{i:X4}");
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@
<Reference Include="System.Diagnostics.Tools" />
<Reference Include="System.Linq" />
<Reference Include="System.Linq.Expressions" />
<Reference Include="System.Memory" />
<Reference Include="System.ObjectModel" />
<Reference Include="System.Reflection" />
<Reference Include="System.Resources.ResourceManager" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ internal static Type GetStructType(int args)
// See if we can find an existing type
foreach (Type t in s_generatedTypes)
{
int arity = int.Parse(t.Name.Substring("VariantArray".Length), CultureInfo.InvariantCulture);
int arity = int.Parse(t.Name.AsSpan("VariantArray".Length), provider: CultureInfo.InvariantCulture);
if (size == arity)
{
return t;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ public override string ToString()
: NativeErrorCode.ToString(CultureInfo.InvariantCulture);
if (HResult == E_FAIL)
{
s.AppendFormat(CultureInfo.InvariantCulture, " ({0})", nativeErrorString);
s.AppendFormat($" ({nativeErrorString})");
}
else
{
s.AppendFormat(CultureInfo.InvariantCulture, " ({0:X8}, {1})", HResult, nativeErrorString);
s.AppendFormat($" ({HResult:X8}, {nativeErrorString})");
}

if (!(string.IsNullOrEmpty(message)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ private void DeleteValueCore(string name, bool throwOnMissingValue)
}
// We really should throw an exception here if errorCode was bad,
// but we can't for compatibility reasons.
Debug.Assert(errorCode == 0, "RegDeleteValue failed. Here's your error code: " + errorCode);
Debug.Assert(errorCode == 0, $"RegDeleteValue failed. Here's your error code: {errorCode}");
}

/// <summary>
Expand Down
Loading