diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-07-06 19:24:49 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-07-06 19:24:49 -0400 |
commit | 4d9fd63d9e890a10029508c7d7e31dcc0b579db7 (patch) | |
tree | c47086a924b0a39bf5e2aaf0323f83e962ddfaa8 | |
parent | 2347644a1fa3537b198d063232ba814769ffe044 (diff) | |
download | SMAPI-4d9fd63d9e890a10029508c7d7e31dcc0b579db7.tar.gz SMAPI-4d9fd63d9e890a10029508c7d7e31dcc0b579db7.tar.bz2 SMAPI-4d9fd63d9e890a10029508c7d7e31dcc0b579db7.zip |
update code annotations
19 files changed, 31 insertions, 27 deletions
diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index 5a6aa747..fd1a6047 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -453,6 +453,7 @@ namespace StardewModdingApi.Installer } // find target folder + // ReSharper disable once ConditionalAccessQualifierIsNonNullableAccordingToAPIContract -- avoid error if the Mods folder has invalid mods, since they're not validated yet ModFolder? targetMod = targetMods.FirstOrDefault(p => p.Manifest?.UniqueID?.Equals(sourceMod.Manifest.UniqueID, StringComparison.OrdinalIgnoreCase) == true); DirectoryInfo defaultTargetFolder = new(Path.Combine(paths.ModsPath, sourceMod.Directory.Name)); DirectoryInfo targetFolder = targetMod?.Directory ?? defaultTargetFolder; diff --git a/src/SMAPI.ModBuildConfig/DeployModTask.cs b/src/SMAPI.ModBuildConfig/DeployModTask.cs index c7026ee1..88412d92 100644 --- a/src/SMAPI.ModBuildConfig/DeployModTask.cs +++ b/src/SMAPI.ModBuildConfig/DeployModTask.cs @@ -227,8 +227,7 @@ namespace StardewModdingAPI.ModBuildConfig string fromPath = entry.Value.FullName; string toPath = Path.Combine(modFolderPath, entry.Key); - // ReSharper disable once AssignNullToNotNullAttribute -- not applicable in this context - Directory.CreateDirectory(Path.GetDirectoryName(toPath)); + Directory.CreateDirectory(Path.GetDirectoryName(toPath)!); File.Copy(fromPath, toPath, overwrite: true); } diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs index 3722e155..88ddfe6b 100644 --- a/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs +++ b/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs @@ -30,7 +30,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework /// <summary>Get all spawnable items.</summary> /// <param name="itemTypes">The item types to fetch (or null for any type).</param> /// <param name="includeVariants">Whether to include flavored variants like "Sunflower Honey".</param> - [SuppressMessage("ReSharper", "AccessToModifiedClosure", Justification = "TryCreate invokes the lambda immediately.")] + [SuppressMessage("ReSharper", "AccessToModifiedClosure", Justification = $"{nameof(ItemRepository.TryCreate)} invokes the lambda immediately.")] public IEnumerable<SearchableItem> GetAll(ItemType[]? itemTypes = null, bool includeVariants = true) { // diff --git a/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs b/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs index 7f06d170..3bdd145a 100644 --- a/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs +++ b/src/SMAPI.Toolkit/Framework/Clients/Wiki/WikiClient.cs @@ -283,8 +283,8 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki } /// <summary>The response model for the MediaWiki parse API.</summary> - [SuppressMessage("ReSharper", "ClassNeverInstantiated.Local")] - [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")] + [SuppressMessage("ReSharper", "ClassNeverInstantiated.Local", Justification = "Used via JSON deserialization.")] + [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local", Justification = "Used via JSON deserialization.")] private class ResponseModel { /********* @@ -306,9 +306,9 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.Wiki } /// <summary>The inner response model for the MediaWiki parse API.</summary> - [SuppressMessage("ReSharper", "ClassNeverInstantiated.Local")] - [SuppressMessage("ReSharper", "CollectionNeverUpdated.Local")] - [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local")] + [SuppressMessage("ReSharper", "ClassNeverInstantiated.Local", Justification = "Used via JSON deserialization.")] + [SuppressMessage("ReSharper", "CollectionNeverUpdated.Local", Justification = "Used via JSON deserialization.")] + [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Local", Justification = "Used via JSON deserialization.")] private class ResponseParseModel { /********* diff --git a/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs b/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs index 6978567e..118b71b2 100644 --- a/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs +++ b/src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs @@ -21,6 +21,7 @@ namespace StardewModdingAPI.Toolkit.Framework /// <summary>Get the OS name from the system uname command.</summary> /// <param name="buffer">The buffer to fill with the resulting string.</param> [DllImport("libc")] + [SuppressMessage("ReSharper", "IdentifierTypo", Justification = "This is the actual external command name.")] static extern int uname(IntPtr buffer); @@ -51,7 +52,6 @@ namespace StardewModdingAPI.Toolkit.Framework /// <summary>Get the human-readable OS name and version.</summary> /// <param name="platform">The current platform.</param> - [SuppressMessage("ReSharper", "EmptyGeneralCatchClause", Justification = "Error suppressed deliberately to fallback to default behaviour.")] public static string GetFriendlyPlatformName(string platform) { #if SMAPI_FOR_WINDOWS @@ -65,7 +65,10 @@ namespace StardewModdingAPI.Toolkit.Framework return result ?? "Windows"; } - catch { } + catch + { + // fallback to default behavior + } #endif string name = Environment.OSVersion.ToString(); diff --git a/src/SMAPI.Web/Framework/Clients/ModDrop/ModDropClient.cs b/src/SMAPI.Web/Framework/Clients/ModDrop/ModDropClient.cs index c60b2c90..f5a5f930 100644 --- a/src/SMAPI.Web/Framework/Clients/ModDrop/ModDropClient.cs +++ b/src/SMAPI.Web/Framework/Clients/ModDrop/ModDropClient.cs @@ -42,7 +42,7 @@ namespace StardewModdingAPI.Web.Framework.Clients.ModDrop /// <summary>Get update check info about a mod.</summary> /// <param name="id">The mod ID.</param> - [SuppressMessage("ReSharper", "ConstantConditionalAccessQualifier", Justification = "The nullability is validated in this method.")] + [SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "The nullability is validated in this method.")] public async Task<IModPage?> GetModData(string id) { IModPage page = new GenericModPage(this.SiteKey, id); diff --git a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs index d7be0c37..54f8e2a2 100644 --- a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs @@ -111,7 +111,6 @@ namespace StardewModdingAPI.Framework.ContentManagers } /// <inheritdoc /> - [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse", Justification = "Copied as-is from game code")] public sealed override string LoadBaseString(string path) { try @@ -119,7 +118,7 @@ namespace StardewModdingAPI.Framework.ContentManagers // copied as-is from LocalizedContentManager.LoadBaseString // This is only changed to call this.Load instead of base.Load, to support mod assets this.ParseStringPath(path, out string assetName, out string key); - Dictionary<string, string> strings = this.Load<Dictionary<string, string>>(assetName, LanguageCode.en); + Dictionary<string, string>? strings = this.Load<Dictionary<string, string>?>(assetName, LanguageCode.en); return strings != null && strings.ContainsKey(key) ? this.GetString(strings, key) : path; diff --git a/src/SMAPI/Framework/Logging/LogManager.cs b/src/SMAPI/Framework/Logging/LogManager.cs index d811ed5c..c0b7c0ba 100644 --- a/src/SMAPI/Framework/Logging/LogManager.cs +++ b/src/SMAPI/Framework/Logging/LogManager.cs @@ -400,7 +400,7 @@ namespace StardewModdingAPI.Framework.Logging /// <param name="mods">The loaded mods.</param> /// <param name="skippedMods">The mods which could not be loaded.</param> /// <param name="logParanoidWarnings">Whether to log issues for mods which directly use potentially sensitive .NET APIs like file or shell access.</param> - [SuppressMessage("ReSharper", "ConstantConditionalAccessQualifier", Justification = "Manifests aren't guaranteed non-null at this point in the loading process.")] + [SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "Manifests aren't guaranteed non-null at this point in the loading process.")] private void LogModWarnings(IEnumerable<IModMetadata> mods, IModMetadata[] skippedMods, bool logParanoidWarnings) { // get mods with warnings diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs index aa4d2d8c..ac7a6bbd 100644 --- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs +++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs @@ -83,7 +83,7 @@ namespace StardewModdingAPI.Framework.ModLoading /// <inheritdoc /> [MemberNotNullWhen(true, nameof(ModMetadata.ContentPack))] - [SuppressMessage("ReSharper", "ConstantConditionalAccessQualifier", Justification = "The manifest may be null for broken mods while loading.")] + [SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "The manifest may be null for broken mods while loading.")] public bool IsContentPack => this.Manifest?.ContentPackFor != null; /// <summary>The fake content packs created by this mod, if any.</summary> diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index 3e7144f9..abc46d47 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -60,8 +60,8 @@ namespace StardewModdingAPI.Framework.ModLoading /// <param name="getUpdateUrl">Get an update URL for an update key (if valid).</param> /// <param name="getFileLookup">Get a file lookup for the given directory.</param> /// <param name="validateFilesExist">Whether to validate that files referenced in the manifest (like <see cref="IManifest.EntryDll"/>) exist on disk. This can be disabled to only validate the manifest itself.</param> - [SuppressMessage("ReSharper", "ConstantConditionalAccessQualifier", Justification = "Manifest values may be null before they're validated.")] - [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse", Justification = "Manifest values may be null before they're validated.")] + [SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "Manifest values may be null before they're validated.")] + [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract", Justification = "Manifest values may be null before they're validated.")] public void ValidateManifests(IEnumerable<IModMetadata> mods, ISemanticVersion apiVersion, Func<string, string?> getUpdateUrl, Func<string, IFileLookup> getFileLookup, bool validateFilesExist = true) { mods = mods.ToArray(); diff --git a/src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyInstanceFacade.cs b/src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyInstanceFacade.cs index 9c8ba2b0..be45272e 100644 --- a/src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyInstanceFacade.cs +++ b/src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyInstanceFacade.cs @@ -28,7 +28,7 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades return new Harmony(id); } - [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse", Justification = "If the user passes a null original method, we let it fail in the underlying Harmony instance instead of handling it here.")] + [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract", Justification = "If the user passes a null original method, we let it fail in the underlying Harmony instance instead of handling it here.")] public DynamicMethod Patch(MethodBase original, HarmonyMethod? prefix = null, HarmonyMethod? postfix = null, HarmonyMethod? transpiler = null) { // In Harmony 1.x you could target a virtual method that's not implemented by the diff --git a/src/SMAPI/Framework/ModLoading/RewriteFacades/SpriteBatchFacade.cs b/src/SMAPI/Framework/ModLoading/RewriteFacades/SpriteBatchFacade.cs index 67569424..3eb31df3 100644 --- a/src/SMAPI/Framework/ModLoading/RewriteFacades/SpriteBatchFacade.cs +++ b/src/SMAPI/Framework/ModLoading/RewriteFacades/SpriteBatchFacade.cs @@ -10,7 +10,6 @@ namespace StardewModdingAPI.Framework.ModLoading.RewriteFacades /// <summary>Provides <see cref="SpriteBatch"/> method signatures that can be injected into mod code for compatibility with mods written for XNA Framework before Stardew Valley 1.5.5.</summary> /// <remarks>This is public to support SMAPI rewriting and should not be referenced directly by mods.</remarks> [SuppressMessage("ReSharper", "UnusedMember.Global", Justification = "Used via assembly rewriting")] - [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Linux/macOS.")] [SuppressMessage("ReSharper", "CS1591", Justification = "Documentation not needed for facade classes.")] public class SpriteBatchFacade : SpriteBatch { diff --git a/src/SMAPI/Framework/Networking/MultiplayerPeerMod.cs b/src/SMAPI/Framework/Networking/MultiplayerPeerMod.cs index 1e150508..cc936489 100644 --- a/src/SMAPI/Framework/Networking/MultiplayerPeerMod.cs +++ b/src/SMAPI/Framework/Networking/MultiplayerPeerMod.cs @@ -22,7 +22,7 @@ namespace StardewModdingAPI.Framework.Networking *********/ /// <summary>Construct an instance.</summary> /// <param name="mod">The mod metadata.</param> - [SuppressMessage("ReSharper", "ConstantConditionalAccessQualifier", Justification = "The ID shouldn't be null, but we should handle it to avoid an error just in case.")] + [SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "The ID shouldn't be null, but we should handle it to avoid an error just in case.")] public MultiplayerPeerMod(RemoteContextModModel mod) { this.Name = mod.Name; diff --git a/src/SMAPI/Framework/Rendering/SXnaDisplayDevice.cs b/src/SMAPI/Framework/Rendering/SXnaDisplayDevice.cs index 94b13378..dac41629 100644 --- a/src/SMAPI/Framework/Rendering/SXnaDisplayDevice.cs +++ b/src/SMAPI/Framework/Rendering/SXnaDisplayDevice.cs @@ -14,7 +14,7 @@ namespace StardewModdingAPI.Framework.Rendering { /// <summary>A map display device which reimplements the default logic.</summary> /// <remarks>This is an exact copy of <see cref="XnaDisplayDevice"/>, except that private fields are protected and all methods are virtual.</remarks> - [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Field naming deliberately matches " + nameof(XnaDisplayDevice) + " to minimize differences.")] + [SuppressMessage("ReSharper", "InconsistentNaming", Justification = $"Field naming deliberately matches {nameof(XnaDisplayDevice)} to minimize differences.")] internal class SXnaDisplayDevice : IDisplayDevice { /********* diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index d0effb03..d9969d4d 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -325,7 +325,7 @@ namespace StardewModdingAPI.Framework } /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary> - [SuppressMessage("ReSharper", "ConstantConditionalAccessQualifier", Justification = "May be disposed before SMAPI is fully initialized.")] + [SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "May be disposed before SMAPI is fully initialized.")] public void Dispose() { // skip if already disposed @@ -1285,7 +1285,7 @@ namespace StardewModdingAPI.Framework private LocalizedContentManager CreateContentManager(IServiceProvider serviceProvider, string rootDirectory) { // Game1._temporaryContent initializing from SGame constructor - // ReSharper disable once ConditionIsAlwaysTrueOrFalse -- this is the method that initializes it + // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -- this is the method that initializes it if (this.ContentCore == null) { this.ContentCore = new ContentCoordinator( @@ -1808,7 +1808,7 @@ namespace StardewModdingAPI.Framework string relativePath = mod.GetRelativePathWithRoot(); if (mod.IsContentPack) this.Monitor.Log($" {mod.DisplayName} (from {relativePath}) [content pack]..."); - // ReSharper disable once ConstantConditionalAccessQualifier -- mod may be invalid at this point + // ReSharper disable once ConditionalAccessQualifierIsNonNullableAccordingToAPIContract -- mod may be invalid at this point else if (mod.Manifest?.EntryDll != null) this.Monitor.Log($" {mod.DisplayName} (from {relativePath}{Path.DirectorySeparatorChar}{mod.Manifest.EntryDll})..."); // don't use Path.Combine here, since EntryDLL might not be valid else diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs index 38043e1c..feb0988a 100644 --- a/src/SMAPI/Framework/SGame.cs +++ b/src/SMAPI/Framework/SGame.cs @@ -252,6 +252,7 @@ namespace StardewModdingAPI.Framework [SuppressMessage("ReSharper", "LocalVariableHidesMember", Justification = "copied from game code as-is")] [SuppressMessage("ReSharper", "MergeIntoPattern", Justification = "copied from game code as-is")] [SuppressMessage("ReSharper", "PossibleLossOfFraction", Justification = "copied from game code as-is")] + [SuppressMessage("ReSharper", "PossibleNullReferenceException", Justification = "copied from game code as-is")] [SuppressMessage("ReSharper", "RedundantArgumentDefaultValue", Justification = "copied from game code as-is")] [SuppressMessage("ReSharper", "RedundantBaseQualifier", Justification = "copied from game code as-is")] [SuppressMessage("ReSharper", "RedundantCast", Justification = "copied from game code as-is")] @@ -261,6 +262,8 @@ namespace StardewModdingAPI.Framework [SuppressMessage("ReSharper", "MergeIntoPattern", Justification = "copied from game code as-is")] [SuppressMessage("SMAPI.CommonErrors", "AvoidImplicitNetFieldCast", Justification = "copied from game code as-is")] [SuppressMessage("SMAPI.CommonErrors", "AvoidNetField", Justification = "copied from game code as-is")] + + [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse", Justification = "Deliberate to minimize chance of errors when copying event calls into new versions of this code.")] private void DrawImpl(GameTime gameTime, RenderTarget2D target_screen) { var events = this.Events; diff --git a/src/SMAPI/Metadata/CoreAssetPropagator.cs b/src/SMAPI/Metadata/CoreAssetPropagator.cs index 1b4d1737..1ef9a8f2 100644 --- a/src/SMAPI/Metadata/CoreAssetPropagator.cs +++ b/src/SMAPI/Metadata/CoreAssetPropagator.cs @@ -966,7 +966,7 @@ namespace StardewModdingAPI.Metadata { // get suspension bridges field var field = this.Reflection.GetField<IEnumerable<SuspensionBridge>?>(location, nameof(IslandNorth.suspensionBridges), required: false); - // ReSharper disable once ConditionIsAlwaysTrueOrFalse -- field is nullable when required: false + // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -- field is nullable when required: false if (field == null || !typeof(IEnumerable<SuspensionBridge>).IsAssignableFrom(field.FieldInfo.FieldType)) continue; diff --git a/src/SMAPI/Translation.cs b/src/SMAPI/Translation.cs index 01cb92b2..5cc119d9 100644 --- a/src/SMAPI/Translation.cs +++ b/src/SMAPI/Translation.cs @@ -121,7 +121,7 @@ namespace StardewModdingAPI /// <summary>Get a string representation of the given translation.</summary> /// <param name="translation">The translation key.</param> /// <remarks><strong>Limitation with nullable reference types: if there's no text and you disabled the fallback via <see cref="UsePlaceholder"/>, this will return null but the return value will still be marked non-nullable.</strong></remarks> - [SuppressMessage("ReSharper", "ConstantConditionalAccessQualifier", Justification = "The null check is required due to limitations in nullable type annotations (see remarks).")] + [SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "The null check is required due to limitations in nullable type annotations (see remarks).")] public static implicit operator string(Translation translation) { return translation?.ToString()!; diff --git a/src/SMAPI/Utilities/SDate.cs b/src/SMAPI/Utilities/SDate.cs index 1d4e4489..c7ad41bd 100644 --- a/src/SMAPI/Utilities/SDate.cs +++ b/src/SMAPI/Utilities/SDate.cs @@ -250,7 +250,7 @@ namespace StardewModdingAPI.Utilities /// <param name="year">The year.</param> /// <param name="allowDayZero">Whether to allow 0 spring Y1 as a valid date.</param> /// <exception cref="ArgumentException">One of the arguments has an invalid value (like day 35).</exception> - [SuppressMessage("ReSharper", "ConstantConditionalAccessQualifier", Justification = "The nullability is validated in this constructor.")] + [SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "The nullability is validated in this constructor.")] private SDate(int day, string season, int year, bool allowDayZero) { season = season?.Trim().ToLowerInvariant()!; // null-checked below |