Skip to content

Commit a0e670a

Browse files
Remove uses of SR.GetResourceString throughout the libs (#87912)
Fixes #81338.
1 parent 5ff4fdd commit a0e670a

File tree

19 files changed

+79
-43
lines changed

19 files changed

+79
-43
lines changed

src/libraries/Common/src/System/SR.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,17 @@ internal static partial class SR
1515
// The trimming tools are also capable of replacing the value of this method when the application is being trimmed.
1616
internal static bool UsingResourceKeys() => s_usingResourceKeys;
1717

18-
internal static string GetResourceString(string resourceKey)
18+
// We can optimize out the resource string blob if we can see all accesses to it happening
19+
// through the generated SR.XXX properties.
20+
// If a call to GetResourceString is left, the optimization gets defeated and we need to keep
21+
// the whole resource blob. It's important to keep this private. CoreCLR's CoreLib gets a free
22+
// pass because the VM needs to be able to call into this, but that's a known set of constants.
23+
#if CORECLR || LEGACY_GETRESOURCESTRING_USER
24+
internal
25+
#else
26+
private
27+
#endif
28+
static string GetResourceString(string resourceKey)
1929
{
2030
if (UsingResourceKeys())
2131
{
@@ -37,7 +47,12 @@ internal static string GetResourceString(string resourceKey)
3747
return resourceString!; // only null if missing resources
3848
}
3949

40-
internal static string GetResourceString(string resourceKey, string defaultString)
50+
#if LEGACY_GETRESOURCESTRING_USER
51+
internal
52+
#else
53+
private
54+
#endif
55+
static string GetResourceString(string resourceKey, string defaultString)
4156
{
4257
string resourceString = GetResourceString(resourceKey);
4358

src/libraries/Microsoft.CSharp/src/Microsoft.CSharp.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<EnableComBinder Condition="'$(TargetPlatformIdentifier)' == 'windows'">true</EnableComBinder>
1010
<DefineConstants Condition="'$(EnableComBinder)' == 'true'">$(DefineConstants);ENABLECOMBINDER</DefineConstants>
1111
<AllowUnsafeBlocks Condition="'$(EnableComBinder)' == 'true'">true</AllowUnsafeBlocks>
12+
<DefineConstants>$(DefineConstants);LEGACY_GETRESOURCESTRING_USER</DefineConstants>
1213
<EnableAOTAnalyzer>false</EnableAOTAnalyzer>
1314
</PropertyGroup>
1415
<ItemGroup>

src/libraries/Microsoft.Extensions.Primitives/src/ThrowHelper.cs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,20 @@ internal static ArgumentException GetArgumentException(ExceptionResource resourc
5858

5959
private static string GetResourceText(ExceptionResource resource)
6060
{
61-
return SR.GetResourceString(GetResourceName(resource));
61+
Debug.Assert(Enum.IsDefined(typeof(ExceptionResource), resource),
62+
"The enum value is not defined, please check the ExceptionResource Enum.");
63+
64+
switch (resource)
65+
{
66+
case ExceptionResource.Argument_InvalidOffsetLength: return SR.Argument_InvalidOffsetLength;
67+
case ExceptionResource.Argument_InvalidOffsetLengthStringSegment: return SR.Argument_InvalidOffsetLengthStringSegment;
68+
case ExceptionResource.Capacity_CannotChangeAfterWriteStarted: return SR.Capacity_CannotChangeAfterWriteStarted;
69+
case ExceptionResource.Capacity_NotEnough: return SR.Capacity_NotEnough;
70+
case ExceptionResource.Capacity_NotUsedEntirely: return SR.Capacity_NotUsedEntirely;
71+
default:
72+
Debug.Fail($"Unexpected resource {resource}");
73+
return "";
74+
}
6275
}
6376

6477
private static string GetArgumentName(ExceptionArgument argument)
@@ -68,14 +81,6 @@ private static string GetArgumentName(ExceptionArgument argument)
6881

6982
return argument.ToString();
7083
}
71-
72-
private static string GetResourceName(ExceptionResource resource)
73-
{
74-
Debug.Assert(Enum.IsDefined(typeof(ExceptionResource), resource),
75-
"The enum value is not defined, please check the ExceptionResource Enum.");
76-
77-
return resource.ToString();
78-
}
7984
}
8085

8186
internal enum ExceptionArgument

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ArrayConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class ArrayConverter : CollectionConverter
1919
{
2020
if (destinationType == typeof(string) && value is Array)
2121
{
22-
return SR.Format(SR.GetResourceString(nameof(SR.Array), "{0} Array"), value.GetType().Name);
22+
return SR.Format(SR.UsingResourceKeys() ? "{0} Array" : SR.Array, value.GetType().Name);
2323
}
2424

2525
return base.ConvertTo(context, culture, value, destinationType);

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CollectionConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class CollectionConverter : TypeConverter
2020
{
2121
if (destinationType == typeof(string) && value is ICollection)
2222
{
23-
return SR.GetResourceString(nameof(SR.Collection), "(Collection)");
23+
return SR.UsingResourceKeys() ? "(Collection)" : SR.Collection;
2424
}
2525

2626
return base.ConvertTo(context, culture, value, destinationType);

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/CultureInfoConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class CultureInfoConverter : TypeConverter
2222
/// <summary>
2323
/// Retrieves the "default" name for our culture.
2424
/// </summary>
25-
private static string DefaultCultureString => SR.GetResourceString(nameof(SR.CultureInfoConverterDefaultCultureString), "(Default)");
25+
private static string DefaultCultureString => SR.UsingResourceKeys() ? "(Default)" : SR.CultureInfoConverterDefaultCultureString;
2626

2727
private const string DefaultInvariantCultureString = "(Default)";
2828

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/Design/DesignerOptionService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContex
461461
{
462462
if (destinationType == typeof(string))
463463
{
464-
return SR.GetResourceString(nameof(SR.CollectionConverterText), "(Collection)");
464+
return SR.UsingResourceKeys() ? "(Collection)" : SR.CollectionConverterText;
465465
}
466466
return base.ConvertTo(cxt, culture, value, destinationType);
467467
}

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ExtendedPropertyDescriptor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public override string DisplayName
9999
string? providerName = site?.Name;
100100
if (providerName != null && providerName.Length > 0)
101101
{
102-
name = SR.Format(SR.GetResourceString(nameof(SR.MetaExtenderName), "{0} on {1}"), name, providerName);
102+
name = SR.Format(SR.UsingResourceKeys() ? "{0} on {1}" : SR.MetaExtenderName, name, providerName);
103103
}
104104
}
105105
return name;

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/InstanceCreationEditor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace System.ComponentModel
1111
/// </summary>
1212
public abstract class InstanceCreationEditor
1313
{
14-
public virtual string Text => SR.GetResourceString(nameof(SR.InstanceCreationEditorDefaultText), "(New...)");
14+
public virtual string Text => SR.UsingResourceKeys() ? "(New...)" : SR.InstanceCreationEditorDefaultText;
1515

1616
/// <summary>
1717
/// This method is invoked when you user chooses the link displayed by the PropertyGrid for the InstanceCreationEditor.

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/MultilineStringConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class MultilineStringConverter : TypeConverter
2020

2121
if (destinationType == typeof(string) && value is string)
2222
{
23-
return SR.GetResourceString(nameof(SR.Text), "(Text)");
23+
return SR.UsingResourceKeys() ? "(Text)" : SR.Text;
2424
}
2525

2626
return base.ConvertTo(context, culture, value, destinationType);

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/ReferenceConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace System.ComponentModel
1515
/// </summary>
1616
public class ReferenceConverter : TypeConverter
1717
{
18-
private static readonly string s_none = SR.GetResourceString(nameof(SR.toStringNone), "(none)");
18+
private static readonly string s_none = SR.UsingResourceKeys() ? "(none)" : SR.toStringNone;
1919
private readonly Type _type;
2020

2121
/// <summary>

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeConverter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ public virtual bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen(t
191191
/// </summary>
192192
protected Exception GetConvertFromException(object? value)
193193
{
194-
string? valueTypeName = value == null ? SR.GetResourceString(nameof(SR.Null), "(null)") : value.GetType().FullName;
194+
string? valueTypeName = value == null ? (SR.UsingResourceKeys() ? "(null)" : SR.Null) : value.GetType().FullName;
195195
throw new NotSupportedException(SR.Format(SR.ConvertFromException, GetType().Name, valueTypeName));
196196
}
197197

@@ -201,7 +201,7 @@ protected Exception GetConvertFromException(object? value)
201201
/// </summary>
202202
protected Exception GetConvertToException(object? value, Type destinationType)
203203
{
204-
string? valueTypeName = value == null ? SR.GetResourceString(nameof(SR.Null), "(null)") : value.GetType().FullName;
204+
string? valueTypeName = value == null ? (SR.UsingResourceKeys() ? "(null)" : SR.Null) : value.GetType().FullName;
205205
throw new NotSupportedException(SR.Format(SR.ConvertToException, GetType().Name, valueTypeName, destinationType.FullName));
206206
}
207207

src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/TypeListConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen(
7373
{
7474
if (value == null)
7575
{
76-
return SR.GetResourceString(nameof(SR.none), "(none)");
76+
return SR.UsingResourceKeys() ? "(none)" : SR.none;
7777
}
7878
else
7979
{

src/libraries/System.ComponentModel.TypeConverter/src/System/Timers/Timer.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public Timer(TimeSpan interval) : this(interval.TotalMilliseconds)
7676
/// Gets or sets a value indicating whether the Timer raises the Tick event each time the specified
7777
/// Interval has elapsed, when Enabled is set to true.
7878
/// </summary>
79-
[TimersDescription(nameof(SR.TimerAutoReset), null), DefaultValue(true)]
79+
[TimersDescription(TimersDescriptionStringId.TimerAutoReset), DefaultValue(true)]
8080
public bool AutoReset
8181
{
8282
get => _autoReset;
@@ -102,7 +102,7 @@ public bool AutoReset
102102
/// is able to raise events at a defined interval.
103103
/// The default value by design is false, don't change it.
104104
/// </summary>
105-
[TimersDescription(nameof(SR.TimerEnabled), null), DefaultValue(false)]
105+
[TimersDescription(TimersDescriptionStringId.TimerEnabled), DefaultValue(false)]
106106
public bool Enabled
107107
{
108108
get => _enabled;
@@ -160,7 +160,7 @@ private void UpdateTimer()
160160
/// <summary>
161161
/// Gets or sets the interval on which to raise events.
162162
/// </summary>
163-
[TimersDescription(nameof(SR.TimerInterval), null), DefaultValue(100d)]
163+
[TimersDescription(TimersDescriptionStringId.TimerInterval), DefaultValue(100d)]
164164
public double Interval
165165
{
166166
get => _interval;
@@ -184,7 +184,7 @@ public double Interval
184184
/// Occurs when the <see cref='System.Timers.Timer.Interval'/> has
185185
/// elapsed.
186186
/// </summary>
187-
[TimersDescription(nameof(SR.TimerIntervalElapsed), null)]
187+
[TimersDescription(TimersDescriptionStringId.TimerIntervalElapsed)]
188188
public event ElapsedEventHandler Elapsed
189189
{
190190
add => _onIntervalElapsed += value;
@@ -212,7 +212,7 @@ public override ISite? Site
212212
/// Gets or sets the object used to marshal event-handler calls that are issued when
213213
/// an interval has elapsed.
214214
/// </summary>
215-
[DefaultValue(null), TimersDescription(nameof(SR.TimerSynchronizingObject), null)]
215+
[DefaultValue(null), TimersDescription(TimersDescriptionStringId.TimerSynchronizingObject)]
216216
public ISynchronizeInvoke? SynchronizingObject
217217
{
218218
get

src/libraries/System.ComponentModel.TypeConverter/src/System/Timers/TimersDescriptionAttribute.cs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,21 @@ public class TimersDescriptionAttribute : DescriptionAttribute
2121
/// </summary>
2222
public TimersDescriptionAttribute(string description) : base(description) { }
2323

24-
/// <summary>
25-
/// Constructs a new localized sys description.
26-
/// </summary>
27-
internal TimersDescriptionAttribute(string description, string? unused) : base(SR.GetResourceString(description))
24+
internal TimersDescriptionAttribute(TimersDescriptionStringId id) : base(GetResourceString(id)) { }
25+
26+
private static string GetResourceString(TimersDescriptionStringId id)
2827
{
29-
// Needed for overload resolution
30-
Debug.Assert(unused == null);
28+
switch (id)
29+
{
30+
case TimersDescriptionStringId.TimerAutoReset: return SR.TimerAutoReset;
31+
case TimersDescriptionStringId.TimerEnabled: return SR.TimerEnabled;
32+
case TimersDescriptionStringId.TimerInterval: return SR.TimerInterval;
33+
case TimersDescriptionStringId.TimerIntervalElapsed: return SR.TimerIntervalElapsed;
34+
case TimersDescriptionStringId.TimerSynchronizingObject: return SR.TimerSynchronizingObject;
35+
default:
36+
Debug.Fail($"Unexpected resource {id}");
37+
return "";
38+
}
3139
}
3240

3341
/// <summary>
@@ -49,4 +57,13 @@ public override string Description
4957
}
5058
}
5159
}
60+
61+
internal enum TimersDescriptionStringId
62+
{
63+
TimerAutoReset,
64+
TimerEnabled,
65+
TimerInterval,
66+
TimerIntervalElapsed,
67+
TimerSynchronizingObject
68+
}
5269
}

src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<IncludeRemoteExecutor>true</IncludeRemoteExecutor>
44
<TargetFrameworks>$(NetCoreAppCurrent);$(NetFrameworkMinimum)</TargetFrameworks>
55
<IgnoreForCI Condition="'$(TargetOS)' == 'browser'">true</IgnoreForCI>
6+
<DefineConstants>$(DefineConstants);LEGACY_GETRESOURCESTRING_USER</DefineConstants>
67
</PropertyGroup>
78
<ItemGroup>
89
<Compile Include="$(CommonTestPath)System\IO\TempDirectory.cs" Link="Common\System\IO\TempDirectory.cs" />

src/libraries/System.Private.CoreLib/src/System/Diagnostics/StackTrace.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,10 @@ internal void ToString(TraceFormat traceFormat, StringBuilder sb)
197197
{
198198
// Passing a default string for "at" in case SR.UsingResourceKeys() is true
199199
// as this is a special case and we don't want to have "Word_At" on stack traces.
200-
string word_At = SR.GetResourceString(nameof(SR.Word_At), defaultString: "at");
200+
string word_At = SR.UsingResourceKeys() ? "at" : SR.Word_At;
201201
// We also want to pass in a default for inFileLineNumber.
202-
string inFileLineNum = SR.GetResourceString(nameof(SR.StackTrace_InFileLineNumber), defaultString: "in {0}:line {1}");
203-
string inFileILOffset = SR.GetResourceString(nameof(SR.StackTrace_InFileILOffset), defaultString: "in {0}:token 0x{1:x}+0x{2:x}");
202+
string inFileLineNum = SR.UsingResourceKeys() ? "in {0}:line {1}" : SR.StackTrace_InFileLineNumber;
203+
string inFileILOffset = SR.UsingResourceKeys() ? "in {0}:token 0x{1:x}+0x{2:x}" : SR.StackTrace_InFileILOffset;
204204
bool fFirstFrame = true;
205205
for (int iFrameIndex = 0; iFrameIndex < _numOfFrames; iFrameIndex++)
206206
{
@@ -340,8 +340,7 @@ internal void ToString(TraceFormat traceFormat, StringBuilder sb)
340340
{
341341
sb.AppendLine();
342342
// Passing default for Exception_EndStackTraceFromPreviousThrow in case SR.UsingResourceKeys is set.
343-
sb.Append(SR.GetResourceString(nameof(SR.Exception_EndStackTraceFromPreviousThrow),
344-
defaultString: "--- End of stack trace from previous location ---"));
343+
sb.Append(SR.UsingResourceKeys() ? "--- End of stack trace from previous location ---" : SR.Exception_EndStackTraceFromPreviousThrow);
345344
}
346345
}
347346
}

src/libraries/System.Text.Encoding.CodePages/src/System/Text/BaseCodePageEncoding.netcoreapp.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,10 @@ internal static unsafe EncodingInfo [] GetEncodings(CodePagesEncodingProvider pr
6666
default: codePageName = new string(&codePageIndex.CodePageName); break;
6767
}
6868

69-
string? resourceName = EncodingNLS.GetLocalizedEncodingNameResource(codePageIndex.CodePage);
7069
string? displayName = null;
71-
72-
if (resourceName != null && resourceName.StartsWith("Globalization_cp_", StringComparison.OrdinalIgnoreCase))
70+
if (!SR.UsingResourceKeys())
7371
{
74-
displayName = SR.GetResourceString(resourceName);
72+
displayName = EncodingNLS.GetLocalizedEncodingNameResource(codePageIndex.CodePage);
7573
}
7674

7775
encodingInfoList[i] = new EncodingInfo(provider, codePageIndex.CodePage, codePageName, displayName ?? codePageName);

src/libraries/System.Transactions.Local/src/System/Transactions/Oletx/OletxTransaction.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ internal Guid Identifier
552552
// for COM+ interop purposes, but we can't get the guid or the status of the transaction.
553553
if (TxGuid.Equals(Guid.Empty))
554554
{
555-
throw TransactionException.Create(SR.GetResourceString(SR.CannotGetTransactionIdentifier), null);
555+
throw TransactionException.Create(SR.CannotGetTransactionIdentifier, null);
556556
}
557557

558558
return TxGuid;

0 commit comments

Comments
 (0)