From f39da383a17b368e92fd243cf155b27ba42671f3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 13 Apr 2022 20:24:14 -0400 Subject: enable nullable annotations in SMAPI where no logic changes are needed (#837) --- .../Framework/ModLoading/Rewriters/HarmonyRewriter.cs | 16 +++++++--------- .../ModLoading/Rewriters/HeuristicFieldRewriter.cs | 19 +++++++++---------- .../ModLoading/Rewriters/HeuristicMethodRewriter.cs | 15 +++++++-------- .../ModLoading/Rewriters/MethodParentRewriter.cs | 13 ++++++------- .../ModLoading/Rewriters/TypeReferenceRewriter.cs | 6 ++---- 5 files changed, 31 insertions(+), 38 deletions(-) (limited to 'src/SMAPI/Framework/ModLoading/Rewriters') diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/HarmonyRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/HarmonyRewriter.cs index 92397c58..aea490c8 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/HarmonyRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/HarmonyRewriter.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using HarmonyLib; using Mono.Cecil; @@ -59,7 +57,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters if (this.ShouldRewrite) { // rewrite Harmony 1.x methods to Harmony 2.0 - MethodReference methodRef = RewriteHelper.AsMethodReference(instruction); + MethodReference? methodRef = RewriteHelper.AsMethodReference(instruction); if (this.TryRewriteMethodsToFacade(module, methodRef)) { this.OnChanged(); @@ -67,7 +65,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters } // rewrite renamed fields - FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction); + FieldReference? fieldRef = RewriteHelper.AsFieldReference(instruction); if (fieldRef != null) { if (fieldRef.DeclaringType.FullName == "HarmonyLib.HarmonyMethod" && fieldRef.Name == "prioritiy") @@ -95,13 +93,13 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// Rewrite methods to use Harmony facades if needed. /// The assembly module containing the method reference. /// The method reference to map. - private bool TryRewriteMethodsToFacade(ModuleDefinition module, MethodReference methodRef) + private bool TryRewriteMethodsToFacade(ModuleDefinition module, MethodReference? methodRef) { if (!this.ReplacedTypes) return false; // not Harmony (or already using Harmony 2.0) // get facade type - Type toType = methodRef?.DeclaringType.FullName switch + Type? toType = methodRef?.DeclaringType.FullName switch { "HarmonyLib.Harmony" => typeof(HarmonyInstanceFacade), "HarmonyLib.AccessTools" => typeof(AccessToolsFacade), @@ -112,9 +110,9 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters return false; // map if there's a matching method - if (RewriteHelper.HasMatchingSignature(toType, methodRef)) + if (RewriteHelper.HasMatchingSignature(toType, methodRef!)) { - methodRef.DeclaringType = module.ImportReference(toType); + methodRef!.DeclaringType = module.ImportReference(toType); return true; } @@ -139,7 +137,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters { string fullName = type.FullName.Replace("Harmony.", "HarmonyLib."); string targetName = typeof(Harmony).AssemblyQualifiedName!.Replace(typeof(Harmony).FullName!, fullName); - return Type.GetType(targetName, throwOnError: true); + return Type.GetType(targetName, throwOnError: true)!; } } } diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/HeuristicFieldRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/HeuristicFieldRewriter.cs index fc06e779..9c6a3980 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/HeuristicFieldRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/HeuristicFieldRewriter.cs @@ -1,6 +1,5 @@ -#nullable disable - using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Mono.Cecil; using Mono.Cecil.Cil; @@ -33,17 +32,17 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters public override bool Handle(ModuleDefinition module, ILProcessor cil, Instruction instruction) { // get field ref - FieldReference fieldRef = RewriteHelper.AsFieldReference(instruction); + FieldReference? fieldRef = RewriteHelper.AsFieldReference(instruction); if (fieldRef == null || !this.ShouldValidate(fieldRef.DeclaringType)) return false; // skip if not broken - FieldDefinition fieldDefinition = fieldRef.Resolve(); + FieldDefinition? fieldDefinition = fieldRef.Resolve(); if (fieldDefinition?.HasConstant == false) return false; // rewrite if possible - TypeDefinition declaringType = fieldRef.DeclaringType.Resolve(); + TypeDefinition? declaringType = fieldRef.DeclaringType.Resolve(); bool isRead = instruction.OpCode == OpCodes.Ldsfld || instruction.OpCode == OpCodes.Ldfld; return this.TryRewriteToProperty(module, instruction, fieldRef, declaringType, isRead) @@ -56,7 +55,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters *********/ /// Whether references to the given type should be validated. /// The type reference. - private bool ShouldValidate(TypeReference type) + private bool ShouldValidate([NotNullWhen(true)] TypeReference? type) { return type != null && this.RewriteReferencesToAssemblies.Contains(type.Scope.Name); } @@ -70,8 +69,8 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters private bool TryRewriteToProperty(ModuleDefinition module, Instruction instruction, FieldReference fieldRef, TypeDefinition declaringType, bool isRead) { // get equivalent property - PropertyDefinition property = declaringType?.Properties.FirstOrDefault(p => p.Name == fieldRef.Name); - MethodDefinition method = isRead ? property?.GetMethod : property?.SetMethod; + PropertyDefinition? property = declaringType?.Properties.FirstOrDefault(p => p.Name == fieldRef.Name); + MethodDefinition? method = isRead ? property?.GetMethod : property?.SetMethod; if (method == null) return false; @@ -86,14 +85,14 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// Try rewriting the field into a matching const field. /// The CIL instruction to rewrite. /// The field definition. - private bool TryRewriteToConstField(Instruction instruction, FieldDefinition field) + private bool TryRewriteToConstField(Instruction instruction, FieldDefinition? field) { // must have been a static field read, and the new field must be const if (instruction.OpCode != OpCodes.Ldsfld || field?.HasConstant != true) return false; // get opcode for value type - Instruction loadInstruction = RewriteHelper.GetLoadValueInstruction(field.Constant); + Instruction? loadInstruction = RewriteHelper.GetLoadValueInstruction(field.Constant); if (loadInstruction == null) return false; diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/HeuristicMethodRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/HeuristicMethodRewriter.cs index 4860072c..601ecbbc 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/HeuristicMethodRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/HeuristicMethodRewriter.cs @@ -1,6 +1,5 @@ -#nullable disable - using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Mono.Cecil; using Mono.Cecil.Cil; @@ -33,7 +32,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters public override bool Handle(ModuleDefinition module, ILProcessor cil, Instruction instruction) { // get method ref - MethodReference methodRef = RewriteHelper.AsMethodReference(instruction); + MethodReference? methodRef = RewriteHelper.AsMethodReference(instruction); if (methodRef == null || !this.ShouldValidate(methodRef.DeclaringType)) return false; @@ -42,13 +41,13 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters return false; // get type - var type = methodRef.DeclaringType.Resolve(); + TypeDefinition? type = methodRef.DeclaringType.Resolve(); if (type == null) return false; // get method definition - MethodDefinition method = null; - foreach (var match in type.Methods.Where(p => p.Name == methodRef.Name)) + MethodDefinition? method = null; + foreach (MethodDefinition match in type.Methods.Where(p => p.Name == methodRef.Name)) { // reference matches initial parameters of definition if (methodRef.Parameters.Count >= match.Parameters.Count || !this.InitialParametersMatch(methodRef, match)) @@ -72,7 +71,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters return false; // SMAPI needs to load the value onto the stack before the method call, but the optional parameter type wasn't recognized // rewrite method reference - foreach (Instruction loadInstruction in loadInstructions) + foreach (Instruction? loadInstruction in loadInstructions) cil.InsertBefore(instruction, loadInstruction); instruction.Operand = module.ImportReference(method); @@ -86,7 +85,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters *********/ /// Whether references to the given type should be validated. /// The type reference. - private bool ShouldValidate(TypeReference type) + private bool ShouldValidate([NotNullWhen(true)] TypeReference? type) { return type != null && this.RewriteReferencesToAssemblies.Contains(type.Scope.Name); } diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs index 00daf337..2e2f6316 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/MethodParentRewriter.cs @@ -1,6 +1,5 @@ -#nullable disable - using System; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Mono.Cecil; using Mono.Cecil.Cil; @@ -28,7 +27,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// The type whose methods to remap. /// The type with methods to map to. /// A brief noun phrase indicating what the instruction finder matches (or null to generate one). - public MethodParentRewriter(string fromType, Type toType, string nounPhrase = null) + public MethodParentRewriter(string fromType, Type toType, string? nounPhrase = null) : base(nounPhrase ?? $"{fromType.Split('.').Last()} methods") { this.FromType = fromType; @@ -39,14 +38,14 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// The type whose methods to remap. /// The type with methods to map to. /// A brief noun phrase indicating what the instruction finder matches (or null to generate one). - public MethodParentRewriter(Type fromType, Type toType, string nounPhrase = null) - : this(fromType.FullName, toType, nounPhrase) { } + public MethodParentRewriter(Type fromType, Type toType, string? nounPhrase = null) + : this(fromType.FullName!, toType, nounPhrase) { } /// public override bool Handle(ModuleDefinition module, ILProcessor cil, Instruction instruction) { // get method ref - MethodReference methodRef = RewriteHelper.AsMethodReference(instruction); + MethodReference? methodRef = RewriteHelper.AsMethodReference(instruction); if (!this.IsMatch(methodRef)) return false; @@ -61,7 +60,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters *********/ /// Get whether a CIL instruction matches. /// The method reference. - private bool IsMatch(MethodReference methodRef) + private bool IsMatch([NotNullWhen(true)] MethodReference? methodRef) { return methodRef != null diff --git a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs index bdc4c4f3..a81cb5be 100644 --- a/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs +++ b/src/SMAPI/Framework/ModLoading/Rewriters/TypeReferenceRewriter.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using Mono.Cecil; using StardewModdingAPI.Framework.ModLoading.Framework; @@ -19,7 +17,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters private readonly Type ToType; /// Get whether a matched type should be ignored. - private readonly Func ShouldIgnore; + private readonly Func? ShouldIgnore; /********* @@ -29,7 +27,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Rewriters /// The full type name to which to find references. /// The new type to reference. /// Get whether a matched type should be ignored. - public TypeReferenceRewriter(string fromTypeFullName, Type toType, Func shouldIgnore = null) + public TypeReferenceRewriter(string fromTypeFullName, Type toType, Func? shouldIgnore = null) : base($"{fromTypeFullName} type") { this.FromTypeName = fromTypeFullName; -- cgit