From 000d12d237f147cf3b041adfa9dc8368e4d401c0 Mon Sep 17 00:00:00 2001 From: Thaddeus Crews Date: Fri, 12 Jan 2024 15:47:50 -0600 Subject: [PATCH] C#: Enforce Globalization code quality rules --- modules/mono/.editorconfig | 9 ---- .../GodotBuildLogger.cs | 2 +- .../GodotTools.Core/StringExtensions.cs | 2 +- .../ForwarderMessageHandler.cs | 5 ++- .../DotNetSolution.cs | 12 ++--- .../GodotTools/GodotTools/Build/BuildInfo.cs | 27 +++++------ .../GodotTools/Build/BuildProblemsFilter.cs | 3 +- .../GodotTools/Build/BuildProblemsView.cs | 31 ++++++------- .../GodotTools/Export/ExportPlugin.cs | 9 ++-- .../GodotTools/GodotTools/GodotSharpEditor.cs | 9 ++-- .../GodotTools/Internals/GodotSharpDirs.cs | 2 +- .../editor/GodotTools/GodotTools/Utils/OS.cs | 4 +- .../glue/GodotSharp/GodotSharp/Core/Color.cs | 13 +++--- .../GodotSharp/Core/DelegateUtils.cs | 7 +-- .../GodotSharp/Core/GodotObject.exceptions.cs | 5 ++- .../glue/GodotSharp/GodotSharp/Core/Plane.cs | 2 + .../GodotSharp/GodotSharp/Core/Projection.cs | 2 + .../GodotSharp/GodotSharp/Core/Quaternion.cs | 2 + .../GodotSharp/Core/StringExtensions.cs | 45 +++++++------------ .../GodotSharp/GodotSharp/Core/Vector2.cs | 2 + .../GodotSharp/GodotSharp/Core/Vector2I.cs | 2 + .../GodotSharp/GodotSharp/Core/Vector3.cs | 2 + .../GodotSharp/GodotSharp/Core/Vector3I.cs | 2 + .../GodotSharp/GodotSharp/Core/Vector4.cs | 2 + .../GodotSharp/GodotSharp/Core/Vector4I.cs | 4 +- 25 files changed, 105 insertions(+), 100 deletions(-) diff --git a/modules/mono/.editorconfig b/modules/mono/.editorconfig index 9434d0693c0..db8fb2921ce 100644 --- a/modules/mono/.editorconfig +++ b/modules/mono/.editorconfig @@ -30,14 +30,5 @@ dotnet_diagnostic.CA1720.severity = none # CA1805: Do not initialize unnecessarily # Don't tell me what to do. dotnet_diagnostic.CA1805.severity = none -# CA1304: Specify CultureInfo -# TODO: We should look into this. -dotnet_diagnostic.CA1304.severity = warning -# CA1305: Specify IFormatProvider -# TODO: We should look into this. Disabled for now because it's annoying. -dotnet_diagnostic.CA1305.severity = none -# CA1310: Specify StringComparison for correctness -# TODO: We should look into this. Disabled for now because it's annoying. -dotnet_diagnostic.CA1310.severity = none # Diagnostics to prevent defensive copies of `in` struct parameters resharper_possibly_impure_method_call_on_readonly_variable_highlighting = error diff --git a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs index 3c46079414a..b699765b8ee 100644 --- a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs +++ b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs @@ -165,7 +165,7 @@ namespace GodotTools.BuildLogger bool hasSpecialChar = value.IndexOfAny(new[] { '\"', '\n', '\r', delimiter }) != -1; if (hasSpecialChar) - return "\"" + value.Replace("\"", "\"\"") + "\""; + return "\"" + value.Replace("\"", "\"\"", StringComparison.Ordinal) + "\""; return value; } diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs index d5c3a923515..2840fa375cf 100644 --- a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs +++ b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs @@ -15,7 +15,7 @@ namespace GodotTools.Core dir = Path.Combine(dir, " ").TrimEnd(); if (Path.DirectorySeparatorChar == '\\') - dir = dir.Replace("/", "\\") + "\\"; + dir = dir.Replace("/", "\\", StringComparison.Ordinal) + "\\"; var fullPath = new Uri(Path.GetFullPath(path), UriKind.Absolute); var relRoot = new Uri(Path.GetFullPath(dir), UriKind.Absolute); diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/ForwarderMessageHandler.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/ForwarderMessageHandler.cs index 3cb6a6687e6..67d55d38977 100644 --- a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/ForwarderMessageHandler.cs +++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/ForwarderMessageHandler.cs @@ -1,3 +1,4 @@ +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -28,7 +29,7 @@ namespace GodotTools.IdeMessaging.CLI { await outputWriter.WriteLineAsync("======= Request ======="); await outputWriter.WriteLineAsync(id); - await outputWriter.WriteLineAsync(content.Body.Count(c => c == '\n').ToString()); + await outputWriter.WriteLineAsync(content.Body.Count(c => c == '\n').ToString(CultureInfo.InvariantCulture)); await outputWriter.WriteLineAsync(content.Body); await outputWriter.WriteLineAsync("======================="); await outputWriter.FlushAsync(); @@ -41,7 +42,7 @@ namespace GodotTools.IdeMessaging.CLI { await outputWriter.WriteLineAsync("======= Response ======="); await outputWriter.WriteLineAsync(id); - await outputWriter.WriteLineAsync(content.Body.Count(c => c == '\n').ToString()); + await outputWriter.WriteLineAsync(content.Body.Count(c => c == '\n').ToString(CultureInfo.InvariantCulture)); await outputWriter.WriteLineAsync(content.Body); await outputWriter.WriteLineAsync("========================"); await outputWriter.FlushAsync(); diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs index ff15b96c1cf..2944dc0d820 100644 --- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs @@ -1,5 +1,7 @@ using GodotTools.Core; +using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Text; @@ -92,8 +94,8 @@ EndProject"; if (!isFirstProject) projectsDecl += "\n"; - projectsDecl += string.Format(_projectDeclaration, - name, projectInfo.PathRelativeToSolution.Replace("/", "\\"), projectInfo.Guid); + projectsDecl += string.Format(CultureInfo.InvariantCulture, _projectDeclaration, + name, projectInfo.PathRelativeToSolution.Replace("/", "\\", StringComparison.Ordinal), projectInfo.Guid); for (int i = 0; i < projectInfo.Configs.Count; i++) { @@ -105,15 +107,15 @@ EndProject"; projPlatformsCfg += "\n"; } - slnPlatformsCfg += string.Format(_solutionPlatformsConfig, config); - projPlatformsCfg += string.Format(_projectPlatformsConfig, projectInfo.Guid, config); + slnPlatformsCfg += string.Format(CultureInfo.InvariantCulture, _solutionPlatformsConfig, config); + projPlatformsCfg += string.Format(CultureInfo.InvariantCulture, _projectPlatformsConfig, projectInfo.Guid, config); } isFirstProject = false; } string solutionPath = Path.Combine(DirectoryPath, Name + ".sln"); - string content = string.Format(_solutionTemplate, projectsDecl, slnPlatformsCfg, projPlatformsCfg); + string content = string.Format(CultureInfo.InvariantCulture, _solutionTemplate, projectsDecl, slnPlatformsCfg, projPlatformsCfg); File.WriteAllText(solutionPath, content, Encoding.UTF8); // UTF-8 with BOM } diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs index be0b7d32221..dc9e2c59200 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs @@ -38,21 +38,18 @@ namespace GodotTools.Build public override int GetHashCode() { - unchecked - { - int hash = 17; - hash = (hash * 29) + Solution.GetHashCode(); - hash = (hash * 29) + Project.GetHashCode(); - hash = (hash * 29) + Configuration.GetHashCode(); - hash = (hash * 29) + (RuntimeIdentifier?.GetHashCode() ?? 0); - hash = (hash * 29) + (PublishOutputDir?.GetHashCode() ?? 0); - hash = (hash * 29) + Restore.GetHashCode(); - hash = (hash * 29) + Rebuild.GetHashCode(); - hash = (hash * 29) + OnlyClean.GetHashCode(); - hash = (hash * 29) + CustomProperties.GetHashCode(); - hash = (hash * 29) + LogsDirPath.GetHashCode(); - return hash; - } + var hash = new HashCode(); + hash.Add(Solution); + hash.Add(Project); + hash.Add(Configuration); + hash.Add(RuntimeIdentifier); + hash.Add(PublishOutputDir); + hash.Add(Restore); + hash.Add(Rebuild); + hash.Add(OnlyClean); + hash.Add(CustomProperties); + hash.Add(LogsDirPath); + return hash.ToHashCode(); } // Needed for instantiation from Godot, after reloading assemblies diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildProblemsFilter.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildProblemsFilter.cs index 2071f687b38..a0db1cdf039 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildProblemsFilter.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildProblemsFilter.cs @@ -1,4 +1,5 @@ using Godot; +using System.Globalization; namespace GodotTools.Build { @@ -16,7 +17,7 @@ namespace GodotTools.Build set { _problemsCount = value; - ToggleButton.Text = _problemsCount.ToString(); + ToggleButton.Text = _problemsCount.ToString(CultureInfo.InvariantCulture); } } diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildProblemsView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildProblemsView.cs index fef169aa07b..b6d6d9ebf8d 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildProblemsView.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildProblemsView.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Text; @@ -83,8 +84,8 @@ namespace GodotTools.Build "error" or _ => BuildDiagnostic.DiagnosticType.Error, }, File = csvColumns[1], - Line = int.Parse(csvColumns[2]), - Column = int.Parse(csvColumns[3]), + Line = int.Parse(csvColumns[2], CultureInfo.InvariantCulture), + Column = int.Parse(csvColumns[3], CultureInfo.InvariantCulture), Code = csvColumns[4], Message = csvColumns[5], ProjectFile = csvColumns[6], @@ -93,7 +94,7 @@ namespace GodotTools.Build // If there's no ProjectFile but the File is a csproj, then use that. if (string.IsNullOrEmpty(diagnostic.ProjectFile) && !string.IsNullOrEmpty(diagnostic.File) && - diagnostic.File.EndsWith(".csproj")) + diagnostic.File.EndsWith(".csproj", StringComparison.OrdinalIgnoreCase)) { diagnostic.ProjectFile = diagnostic.File; } @@ -151,9 +152,9 @@ namespace GodotTools.Build foreach (var diagnostic in selectedDiagnostics) { if (!string.IsNullOrEmpty(diagnostic.Code)) - sb.Append($"{diagnostic.Code}: "); + sb.Append(CultureInfo.InvariantCulture, $"{diagnostic.Code}: "); - sb.AppendLine($"{diagnostic.Message} {diagnostic.File}({diagnostic.Line},{diagnostic.Column})"); + sb.AppendLine(CultureInfo.InvariantCulture, $"{diagnostic.Message} {diagnostic.File}({diagnostic.Line},{diagnostic.Column})"); } string text = sb.ToString(); @@ -251,7 +252,7 @@ namespace GodotTools.Build file = ProjectSettings.LocalizePath(file); - if (file.StartsWith("res://")) + if (file.StartsWith("res://", StringComparison.Ordinal)) { var script = (Script)ResourceLoader.Load(file, typeHint: Internal.CSharpLanguageType); @@ -426,7 +427,7 @@ namespace GodotTools.Build ? Path.GetRelativePath(projectDir, file) : "Unknown file".TTR(); - string fileItemText = string.Format("{0} ({1} issues)".TTR(), relativeFilePath, fileDiagnostics.Length); + string fileItemText = string.Format(CultureInfo.InvariantCulture, "{0} ({1} issues)".TTR(), relativeFilePath, fileDiagnostics.Length); var fileItem = _problemsTree.CreateItem(projectItem); fileItem.SetText(0, fileItemText); @@ -468,10 +469,10 @@ namespace GodotTools.Build shortMessage = shortMessage[..lineBreakIdx]; text.Append(shortMessage); - tooltip.Append($"Message: {diagnostic.Message}"); + tooltip.Append(CultureInfo.InvariantCulture, $"Message: {diagnostic.Message}"); if (!string.IsNullOrEmpty(diagnostic.Code)) - tooltip.Append($"\nCode: {diagnostic.Code}"); + tooltip.Append(CultureInfo.InvariantCulture, $"\nCode: {diagnostic.Code}"); string type = diagnostic.Type switch { @@ -481,7 +482,7 @@ namespace GodotTools.Build BuildDiagnostic.DiagnosticType.Error => "error", _ => "unknown", }; - tooltip.Append($"\nType: {type}"); + tooltip.Append(CultureInfo.InvariantCulture, $"\nType: {type}"); if (!string.IsNullOrEmpty(diagnostic.File)) { @@ -491,15 +492,15 @@ namespace GodotTools.Build text.Append(diagnostic.File); } - text.Append($"({diagnostic.Line},{diagnostic.Column})"); + text.Append(CultureInfo.InvariantCulture, $"({diagnostic.Line},{diagnostic.Column})"); - tooltip.Append($"\nFile: {diagnostic.File}"); - tooltip.Append($"\nLine: {diagnostic.Line}"); - tooltip.Append($"\nColumn: {diagnostic.Column}"); + tooltip.Append(CultureInfo.InvariantCulture, $"\nFile: {diagnostic.File}"); + tooltip.Append(CultureInfo.InvariantCulture, $"\nLine: {diagnostic.Line}"); + tooltip.Append(CultureInfo.InvariantCulture, $"\nColumn: {diagnostic.Column}"); } if (!string.IsNullOrEmpty(diagnostic.ProjectFile)) - tooltip.Append($"\nProject: {diagnostic.ProjectFile}"); + tooltip.Append(CultureInfo.InvariantCulture, $"\nProject: {diagnostic.ProjectFile}"); return new ProblemItem() { diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index 372c4b114bf..46020fda895 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -12,6 +12,7 @@ using Directory = GodotTools.Utils.Directory; using File = GodotTools.Utils.File; using OS = GodotTools.Utils.OS; using Path = System.IO.Path; +using System.Globalization; namespace GodotTools.Export { @@ -277,7 +278,7 @@ namespace GodotTools.Export if (platform == OS.Platforms.iOS) { // Exclude dsym folders. - return !dir.EndsWith(".dsym", StringComparison.InvariantCultureIgnoreCase); + return !dir.EndsWith(".dsym", StringComparison.OrdinalIgnoreCase); } return true; @@ -297,7 +298,7 @@ namespace GodotTools.Export if (platform == OS.Platforms.iOS) { // Don't recurse into dsym folders. - return !dir.EndsWith(".dsym", StringComparison.InvariantCultureIgnoreCase); + return !dir.EndsWith(".dsym", StringComparison.OrdinalIgnoreCase); } return true; @@ -313,13 +314,13 @@ namespace GodotTools.Export byte[] fileData = File.ReadAllBytes(path); string hash = Convert.ToBase64String(SHA512.HashData(fileData)); - manifest.Append($"{filePath}\t{hash}\n"); + manifest.Append(CultureInfo.InvariantCulture, $"{filePath}\t{hash}\n"); AddFile($"res://.godot/mono/publish/{arch}/{filePath}", fileData, false); } else { - if (platform == OS.Platforms.iOS && path.EndsWith(".dat")) + if (platform == OS.Platforms.iOS && path.EndsWith(".dat", StringComparison.OrdinalIgnoreCase)) { AddIosBundleFile(path); } diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index dcbcc4352b5..ef9437066e8 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -4,6 +4,7 @@ using GodotTools.Export; using GodotTools.Utils; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using GodotTools.Build; @@ -202,10 +203,10 @@ namespace GodotTools var insideQuotes = false; var hasFileFlag = false; - execArgs = execArgs.ReplaceN("{line}", line.ToString()); - execArgs = execArgs.ReplaceN("{col}", col.ToString()); + execArgs = execArgs.ReplaceN("{line}", line.ToString(CultureInfo.InvariantCulture)); + execArgs = execArgs.ReplaceN("{col}", col.ToString(CultureInfo.InvariantCulture)); execArgs = execArgs.StripEdges(true, true); - execArgs = execArgs.Replace("\\\\", "\\"); + execArgs = execArgs.Replace("\\\\", "\\", StringComparison.Ordinal); for (int i = 0; i < execArgs.Length; ++i) { @@ -225,7 +226,7 @@ namespace GodotTools } var arg = execArgs.Substr(from, numChars); - if (arg.Contains("{file}")) + if (arg.Contains("{file}", StringComparison.OrdinalIgnoreCase)) { hasFileFlag = true; } diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs index 94499c4f380..3b761577ae8 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs @@ -73,7 +73,7 @@ namespace GodotTools.Internals string? slnParentDir = (string?)ProjectSettings.GetSetting("dotnet/project/solution_directory"); if (string.IsNullOrEmpty(slnParentDir)) slnParentDir = "res://"; - else if (!slnParentDir.StartsWith("res://")) + else if (!slnParentDir.StartsWith("res://", System.StringComparison.Ordinal)) slnParentDir = "res://" + slnParentDir; // The csproj should be in the same folder as project.godot. diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs index d5d8de93d2f..355264e4b3b 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs @@ -274,7 +274,7 @@ namespace GodotTools.Utils if (builder.Length > 0) builder.Append(' '); - if (fileName.Contains(' ')) + if (fileName.Contains(' ', StringComparison.Ordinal)) { builder.Append('"'); builder.Append(fileName); @@ -297,7 +297,7 @@ namespace GodotTools.Utils if (builder.Length > 0) builder.Append(' '); - if (argument.Contains(' ')) + if (argument.Contains(' ', StringComparison.Ordinal)) { builder.Append('"'); builder.Append(argument); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index 772209064cf..c29a0f2bd88 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.Runtime.InteropServices; using Godot.NativeInterop; @@ -776,11 +777,11 @@ namespace Godot private static bool FindNamedColor(string name, out Color color) { - name = name.Replace(" ", string.Empty); - name = name.Replace("-", string.Empty); - name = name.Replace("_", string.Empty); - name = name.Replace("'", string.Empty); - name = name.Replace(".", string.Empty); + name = name.Replace(" ", string.Empty, StringComparison.Ordinal); + name = name.Replace("-", string.Empty, StringComparison.Ordinal); + name = name.Replace("_", string.Empty, StringComparison.Ordinal); + name = name.Replace("'", string.Empty, StringComparison.Ordinal); + name = name.Replace(".", string.Empty, StringComparison.Ordinal); name = name.ToUpperInvariant(); return Colors.namedColors.TryGetValue(name, out color); @@ -1329,7 +1330,9 @@ namespace Godot /// A string representation of this color. public readonly string ToString(string? format) { +#pragma warning disable CA1305 // Disable warning: "Specify IFormatProvider" return $"({R.ToString(format)}, {G.ToString(format)}, {B.ToString(format)}, {A.ToString(format)})"; +#pragma warning restore CA1305 } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs index ab2e0a78b9a..fc6e7a3ebe0 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; @@ -698,7 +699,7 @@ namespace Godot case GodotObject godotObject: return VariantUtils.CreateFrom(godotObject); case Enum @enum: - return VariantUtils.CreateFrom(Convert.ToInt64(@enum)); + return VariantUtils.CreateFrom(Convert.ToInt64(@enum, CultureInfo.InvariantCulture)); case Collections.IGenericGodotDictionary godotDictionary: return VariantUtils.CreateFrom(godotDictionary.UnderlyingDictionary); case Collections.IGenericGodotArray godotArray: @@ -777,7 +778,7 @@ namespace Godot return func(variant); if (typeof(GodotObject).IsAssignableFrom(type)) - return Convert.ChangeType(VariantUtils.ConvertTo(variant), type); + return Convert.ChangeType(VariantUtils.ConvertTo(variant), type, CultureInfo.InvariantCulture); if (typeof(GodotObject[]).IsAssignableFrom(type)) { @@ -796,7 +797,7 @@ namespace Godot } using var godotArray = NativeFuncs.godotsharp_variant_as_array(variant); - return Convert.ChangeType(ConvertToSystemArrayOfGodotObject(godotArray, type), type); + return Convert.ChangeType(ConvertToSystemArrayOfGodotObject(godotArray, type), type, CultureInfo.InvariantCulture); } if (type.IsEnum) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.exceptions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.exceptions.cs index a7640043cef..8195828de94 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.exceptions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotObject.exceptions.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Text; #nullable enable @@ -73,7 +74,7 @@ namespace Godot if (!string.IsNullOrEmpty(_nativeClassName)) { - sb.Append($" (Method '{_nativeClassName}')"); + sb.Append(CultureInfo.InvariantCulture, $" (Method '{_nativeClassName}')"); } return sb.ToString(); @@ -131,7 +132,7 @@ namespace Godot if (!string.IsNullOrEmpty(_nativeMethodName)) { - sb.Append($" (Method '{_nativeMethodName}')"); + sb.Append(CultureInfo.InvariantCulture, $" (Method '{_nativeMethodName}')"); } return sb.ToString(); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs index f5dc34d824e..c5998eca5c0 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs @@ -435,7 +435,9 @@ namespace Godot /// A string representation of this plane. public readonly string ToString(string? format) { +#pragma warning disable CA1305 // Disable warning: "Specify IFormatProvider" return $"{_normal.ToString(format)}, {_d.ToString(format)}"; +#pragma warning restore CA1305 } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs index a646caad3e9..2aac23d7996 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs @@ -1023,10 +1023,12 @@ namespace Godot /// A string representation of this projection. public readonly string ToString(string? format) { +#pragma warning disable CA1305 // Disable warning: "Specify IFormatProvider" return $"{X.X.ToString(format)}, {X.Y.ToString(format)}, {X.Z.ToString(format)}, {X.W.ToString(format)}\n" + $"{Y.X.ToString(format)}, {Y.Y.ToString(format)}, {Y.Z.ToString(format)}, {Y.W.ToString(format)}\n" + $"{Z.X.ToString(format)}, {Z.Y.ToString(format)}, {Z.Z.ToString(format)}, {Z.W.ToString(format)}\n" + $"{W.X.ToString(format)}, {W.Y.ToString(format)}, {W.Z.ToString(format)}, {W.W.ToString(format)}\n"; +#pragma warning restore CA1305 } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs index 2344e8c5104..6a8cb1ba042 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs @@ -822,7 +822,9 @@ namespace Godot /// A string representation of this quaternion. public readonly string ToString(string? format) { +#pragma warning disable CA1305 // Disable warning: "Specify IFormatProvider" return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)}, {W.ToString(format)})"; +#pragma warning restore CA1305 } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs index e89bbbd3708..f249bac69c5 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs @@ -106,7 +106,7 @@ namespace Godot instance = instance.Substring(1); } - if (instance.StartsWith("0b")) + if (instance.StartsWith("0b", StringComparison.OrdinalIgnoreCase)) { instance = instance.Substring(2); } @@ -314,7 +314,7 @@ namespace Godot /// The capitalized string. public static string Capitalize(this string instance) { - string aux = instance.CamelcaseToUnderscore(true).Replace("_", " ").Trim(); + string aux = instance.CamelcaseToUnderscore(true).Replace("_", " ", StringComparison.Ordinal).Trim(); string cap = string.Empty; for (int i = 0; i < aux.GetSliceCount(" "); i++) @@ -742,7 +742,7 @@ namespace Godot byte[] ret = new byte[len]; for (int i = 0; i < len; i++) { - ret[i] = (byte)int.Parse(instance.AsSpan(i * 2, 2), NumberStyles.AllowHexSpecifier); + ret[i] = (byte)int.Parse(instance.AsSpan(i * 2, 2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture); } return ret; } @@ -816,12 +816,12 @@ namespace Godot instance = instance.Substring(1); } - if (instance.StartsWith("0x")) + if (instance.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) { instance = instance.Substring(2); } - return sign * int.Parse(instance, NumberStyles.HexNumber); + return sign * int.Parse(instance, NumberStyles.HexNumber, CultureInfo.InvariantCulture); } /// @@ -878,7 +878,7 @@ namespace Godot if (string.IsNullOrEmpty(instance)) return false; else if (instance.Length > 1) - return instance[0] == '/' || instance[0] == '\\' || instance.Contains(":/") || instance.Contains(":\\"); + return instance[0] == '/' || instance[0] == '\\' || instance.Contains(":/", StringComparison.Ordinal) || instance.Contains(":\\", StringComparison.Ordinal); else return instance[0] == '/' || instance[0] == '\\'; } @@ -1120,7 +1120,7 @@ namespace Godot /// If the string contains a valid IP address. public static bool IsValidIPAddress(this string instance) { - if (instance.Contains(':')) + if (instance.Contains(':', StringComparison.Ordinal)) { string[] ip = instance.Split(':'); @@ -1404,23 +1404,10 @@ namespace Godot return instance + "/" + file; } - /// - /// Replace occurrences of a substring for different ones inside the string. - /// - /// - /// The string to modify. - /// The substring to be replaced in the string. - /// The substring that replaces . - /// The string with the substring occurrences replaced. - public static string Replace(this string instance, string what, string forwhat) - { - return instance.Replace(what, forwhat); - } - /// /// Replace occurrences of a substring for different ones inside the string, but search case-insensitive. /// - /// + /// /// The string to modify. /// The substring to be replaced in the string. /// The substring that replaces . @@ -1634,7 +1621,7 @@ namespace Godot if (end < 0) end = len; if (allowEmpty || end > from) - ret.Add(float.Parse(instance.Substring(from))); + ret.Add(float.Parse(instance.Substring(from), CultureInfo.InvariantCulture)); if (end == len) break; @@ -1738,7 +1725,7 @@ namespace Godot /// The number representation of the string. public static float ToFloat(this string instance) { - return float.Parse(instance); + return float.Parse(instance, CultureInfo.InvariantCulture); } /// @@ -1749,7 +1736,7 @@ namespace Godot /// The number representation of the string. public static int ToInt(this string instance) { - return int.Parse(instance); + return int.Parse(instance, CultureInfo.InvariantCulture); } /// @@ -1802,7 +1789,7 @@ namespace Godot /// A copy of the string with the prefix string removed from the start. public static string TrimPrefix(this string instance, string prefix) { - if (instance.StartsWith(prefix)) + if (instance.StartsWith(prefix, StringComparison.Ordinal)) return instance.Substring(prefix.Length); return instance; @@ -1816,7 +1803,7 @@ namespace Godot /// A copy of the string with the suffix string removed from the end. public static string TrimSuffix(this string instance, string suffix) { - if (instance.EndsWith(suffix)) + if (instance.EndsWith(suffix, StringComparison.Ordinal)) return instance.Substring(0, instance.Length - suffix.Length); return instance; @@ -1833,7 +1820,7 @@ namespace Godot /// The unescaped string. public static string URIDecode(this string instance) { - return Uri.UnescapeDataString(instance.Replace("+", "%20")); + return Uri.UnescapeDataString(instance.Replace("+", "%20", StringComparison.Ordinal)); } /// @@ -1860,10 +1847,10 @@ namespace Godot /// The string sanitized as a valid node name. public static string ValidateNodeName(this string instance) { - string name = instance.Replace(_invalidNodeNameCharacters[0], ""); + string name = instance.Replace(_invalidNodeNameCharacters[0], "", StringComparison.Ordinal); for (int i = 1; i < _invalidNodeNameCharacters.Length; i++) { - name = name.Replace(_invalidNodeNameCharacters[i], ""); + name = name.Replace(_invalidNodeNameCharacters[i], "", StringComparison.Ordinal); } return name; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index a27a1ab1cf9..bd92e48bcea 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -1021,7 +1021,9 @@ namespace Godot /// A string representation of this vector. public readonly string ToString(string? format) { +#pragma warning disable CA1305 // Disable warning: "Specify IFormatProvider" return $"({X.ToString(format)}, {Y.ToString(format)})"; +#pragma warning restore CA1305 } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs index 8960323754a..1a386d9da1f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs @@ -600,7 +600,9 @@ namespace Godot /// A string representation of this vector. public readonly string ToString(string? format) { +#pragma warning disable CA1305 // Disable warning: "Specify IFormatProvider" return $"({X.ToString(format)}, {Y.ToString(format)})"; +#pragma warning restore CA1305 } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index 54d698345f4..6e77512fc86 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -1123,7 +1123,9 @@ namespace Godot /// A string representation of this vector. public readonly string ToString(string? format) { +#pragma warning disable CA1305 // Disable warning: "Specify IFormatProvider" return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)})"; +#pragma warning restore CA1305 } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs index 2d7bbc926db..d0ad1922f61 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs @@ -655,7 +655,9 @@ namespace Godot /// A string representation of this vector. public readonly string ToString(string? format) { +#pragma warning disable CA1305 // Disable warning: "Specify IFormatProvider" return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)})"; +#pragma warning restore CA1305 } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs index 87c01ad5ea6..115e65bbdb0 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs @@ -905,7 +905,9 @@ namespace Godot /// A string representation of this vector. public readonly string ToString(string? format) { +#pragma warning disable CA1305 // Disable warning: "Specify IFormatProvider" return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)}, {W.ToString(format)})"; +#pragma warning restore CA1305 } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs index 9a85f359d7e..527c8e5022c 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs @@ -676,7 +676,9 @@ namespace Godot /// A string representation of this vector. public readonly string ToString(string? format) { - return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)}), {W.ToString(format)})"; +#pragma warning disable CA1305 // Disable warning: "Specify IFormatProvider" + return $"({X.ToString(format)}, {Y.ToString(format)}, {Z.ToString(format)}, {W.ToString(format)})"; +#pragma warning restore CA1305 } } }