diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/ContentManagerAnalyzerTests.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/ContentManagerAnalyzerTests.cs index 743c3fb41..0717e4ec3 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/ContentManagerAnalyzerTests.cs +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/ContentManagerAnalyzerTests.cs @@ -82,7 +82,7 @@ public void EmptyCode_HasNoDiagnostics() /// The expression which should be reported. /// The net type name which should be reported. /// The suggested property name which should be reported. - [TestCase("Game1.content.Load>(\"Data\\\\Fish\");", 0, "Data\\Fish", "System.Collections.Generic.Dictionary", "System.Collections.Generic.Dictionary")] + [TestCase("Game1.content.Load>(\"Data\\\\Fish\");", 0, "Data\\Fish", "System.Collections.Generic.Dictionary", "System.Collections.Generic.Dictionary")] public void BadType_RaisesDiagnostic(string codeText, int column, string assetName, string expectedType, string suggestedType) { // arrange diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Game1.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Game1.cs new file mode 100644 index 000000000..b5849eaf0 --- /dev/null +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Game1.cs @@ -0,0 +1,7 @@ +namespace StardewValley +{ + public class Game1 + { + public static LocalizedContentManager content = new(); + } +} diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/LocalizedContentManager.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/LocalizedContentManager.cs new file mode 100644 index 000000000..3b88a8c56 --- /dev/null +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/LocalizedContentManager.cs @@ -0,0 +1,13 @@ +// ReSharper disable CheckNamespace, InconsistentNaming -- matches Stardew Valley's code +// ReSharper disable UnusedMember.Global -- used dynamically for unit tests +namespace StardewValley +{ + /// A simplified version of Stardew Valley's StardewValley.LocalizedContentManager class for unit testing. + public class LocalizedContentManager + { + public T Load(string assetName) + { + return default!; + } + } +} diff --git a/src/SMAPI.ModBuildConfig.Analyzer/ContentManagerAnalyzer.cs b/src/SMAPI.ModBuildConfig.Analyzer/ContentManagerAnalyzer.cs index 7a1403310..f894d4972 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer/ContentManagerAnalyzer.cs +++ b/src/SMAPI.ModBuildConfig.Analyzer/ContentManagerAnalyzer.cs @@ -70,6 +70,9 @@ private void AnalyzeContentManagerLoads(SyntaxNodeAnalysisContext context) var memberAccess = invocation.Expression as MemberAccessExpressionSyntax; if (memberAccess == null || memberAccess.Name.Identifier.ValueText != "Load") return; + string? loadNamespace = context.SemanticModel.GetSymbolInfo(memberAccess).Symbol?.ContainingNamespace.Name; + if (!(loadNamespace == "StardewValley" || loadNamespace == "StardewModdingAPI")) + return; // "Data\\Fish" -> Data\Fish string assetName = invocation.ArgumentList.Arguments[0].ToString().Replace("\"", "").Replace("\\\\", "\\"); @@ -78,6 +81,8 @@ private void AnalyzeContentManagerLoads(SyntaxNodeAnalysisContext context) if (this.OneSixRules.AssetMap.TryGetValue(assetName, out string expectedType)) { + // delete `3 as I can't convince Roslyn and Cecil to agree + // TODO: Move into DataGeneration expectedType = Regex.Replace(expectedType, "`\\d+", ""); if (genericArgument != expectedType) {