-
Notifications
You must be signed in to change notification settings - Fork 531
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
[build] enable CA1305 for most projects #7993
Conversation
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
Context: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305 Context: https://learn.microsoft.com/dotnet/csharp/tutorials/string-interpolation#how-to-create-a-culture-specific-result-string-with-string-interpolation In b1079a0, we found a real bug where omitting `CultureInfo.InvariantCulture` caused a problem under certain locales. Let's take this a step further by making `CA1305` a build error. In every case I found, it seemed that invariant culture was fine -- and some might be bugs? This also catches cases like this that use the current culture: $"My integer: {x}" Where we should do this instead: FormattableString.Invariant($"My integer: {x}") Only a single instance for displaying a localized string/error message from MSBuild seemed like it needed the current culture: string.Format (CultureInfo.CurrentCulture, Resources.XA2000, assembly)); And this one might not even matter, really? Some projects that are not shipped I didn't enable yet, to keep this change smaller: * Projects in `build-tools` * MSBuild test projects
It might be simpler to add a new |
I made this change, and the diff is a lot smaller now. Only projects in |
@@ -530,7 +531,7 @@ public void RegisterNativeMembers (JniType nativeClass, Type type, ReadOnlySpan< | |||
} | |||
|
|||
if (minfo == null) | |||
throw new InvalidOperationException (String.Format ("Specified managed method '{0}' was not found. Signature: {1}", mname.ToString (), signature.ToString ())); | |||
throw new InvalidOperationException (FormattableString.Invariant ($"Specified managed method '{mname.ToString ()}' was not found. Signature: {signature.ToString ()}")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this should either use {mname}…{signature}
or use {mname.ToString(CultureInfo.InvariantCulture)}…{signature.ToString(CultureInfo.InvariantCulture)
. What is here will call .ToString()
with whatever is the current culture, which is most likely not the Invariant culture, and then pass the output of .ToString()
on to FormattableString.Invariant()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For these two you have to call ToString()
because they are both ReadonlySpan<char>
.
For some reason you can't string interpolate these like $"Foo: {foo}"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, "playing around" in csharp
:
CultureInfo.CurrentCulture = new CultureInfo("de-DE");
double d = 42.5;
d.ToString(); // "42,5"
FormattableString.Invariant($"{d}"); // "42.5"
FormattableString.Invariant($"{d.ToString()}"); // "42,5"
d.ToString()
is "immediate", and thus uses the current culture ("de-DE", German), which is not Invariant output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this change, we'd get a CA1305 build error if these were wrong. ReadonlySpan<char>
doesn't have an overload for ToString()
:
https://learn.microsoft.com/en-us/dotnet/api/system.readonlyspan-1.tostring?view=net-8.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In such cases we should use code like this
@@ -0,0 +1,2 @@ | |||
[*.{cs,vb}] | |||
dotnet_diagnostic.CA1305.severity = error # Specify IFormatProvider |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why enable this just in src
and not repo-wide?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because of the suggestion here: #7993 (comment)
There were a lot of tests, build-tools, Mono.Options, etc. that would also need to be addressed or use $(NoWarn)
.
src/Mono.Android/Android.Util/Log.cs
Outdated
/// <summary> | ||
/// IFormatProvider passed to any underlying string.Format() calls. Defaults to System.Globalization.CultureInfo.CurrentCulture. | ||
/// </summary> | ||
public static IFormatProvider FormatProvider { get; set; } = CultureInfo.CurrentCulture; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doh, one last change: this should be wrapped in a #if ANDROID_34
block, as we shouldn't be updating API-33!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably just change visibility?
#if ANDROID_34
public
#endif
static IFormatProvider FormatProvider { get; set; } = CultureInfo.CurrentCulture;
Commit message: Context: b1079a0e02117b626dd98f8f8608be470056ce3f
Context: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305
Context: https://learn.microsoft.com/dotnet/csharp/tutorials/string-interpolation#how-to-create-a-culture-specific-result-string-with-string-interpolation
In b1079a0e, we found a real bug where omitting
`CultureInfo.InvariantCulture` caused problems under certain locales.
Let's take this a step further by making `CA1305` a build error.
In every case I found, it seemed that invariant culture was fine, and
some might be bugs?
This also catches cases like this that use the current culture:
$"My integer: {x}"
Where we should do this instead:
FormattableString.Invariant($"My integer: {x}")
Only a single instance for displaying a localized string/error
message from MSBuild seemed like it needed the current culture:
string.Format (CultureInfo.CurrentCulture, Resources.XA2000, assembly);
And this one might not even matter, as `assembly` is a string.
For on-device app execution, add a new
`Android.Util.Log.FormatProvider` property, which is used by all the
log methods. This mirrors [`TextWriter.FormatProvider`][1]:
namespace Android.Util {
partial class Log {
public static IFormatProvider FormatProvider { get; set; } = CultureInfo.CurrentCulture;
public static int Debug (string tag, string format, params object[] args) =>
Debug (tag, string.Format (FormatProvider, format, args));
}
}
Some projects that are not shipped I didn't enable yet, to keep this
change smaller:
* Projects in `build-tools`
* MSBuild test projects
* Use `src/.editorconfig`; see also
[`.editorconfig` File hierarchy and precedence][0]
Finally, `build-tools/automation/guardian/source.gdnsuppress` needed
to be updated because the existing `Log.Wtf()` methods were changed
to use the new `Log.FormatProvider` property.
[0]: https://learn.microsoft.com/visualstudio/ide/create-portable-custom-editor-options#file-hierarchy-and-precedence
[1]: https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.formatprovider?view=net-8.0 |
* main: [build] enable CA1305 for most projects (dotnet#7993) Bump to xamarin/monodroid@5aed7edd (dotnet#8043)
Context: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305
Context: https://learn.microsoft.com/dotnet/csharp/tutorials/string-interpolation#how-to-create-a-culture-specific-result-string-with-string-interpolation
In b1079a0, we found a real bug where omitting
CultureInfo.InvariantCulture
caused a problem under certain locales.Let's take this a step further by making
CA1305
a build error. In every case I found, it seemed that invariant culture was fine -- and some might be bugs?This also catches cases like this that use the current culture:
Where we should do this instead:
Only a single instance for displaying a localized string/error message from MSBuild seemed like it needed the current culture:
And this one might not even matter, really?
Some projects that are not shipped I didn't enable yet, to keep this change smaller:
Projects in
build-tools
MSBuild test projects