From 6d8cf614a24ab69baffa89c351b9a22776741442 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 14 Apr 2018 19:51:50 -0400 Subject: don't warn for NetList conversion to implemented interface (#471) --- .../Mock/Netcode/NetList.cs | 9 +++++++++ .../Mock/Netcode/NetObjectList.cs | 6 ++++++ .../Mock/StardewValley/Farmer.cs | 11 ++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetList.cs create mode 100644 src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetObjectList.cs (limited to 'src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock') diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetList.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetList.cs new file mode 100644 index 00000000..1699f71c --- /dev/null +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetList.cs @@ -0,0 +1,9 @@ +// ReSharper disable CheckNamespace -- matches Stardew Valley's code +using System.Collections; +using System.Collections.Generic; + +namespace Netcode +{ + /// A simplified version of Stardew Valley's Netcode.NetObjectList for unit testing. + public class NetList : List, IList, ICollection, IEnumerable, IEnumerable { } +} diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetObjectList.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetObjectList.cs new file mode 100644 index 00000000..7814e7d6 --- /dev/null +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetObjectList.cs @@ -0,0 +1,6 @@ +// ReSharper disable CheckNamespace -- matches Stardew Valley's code +namespace Netcode +{ + /// A simplified version of Stardew Valley's Netcode.NetObjectList for unit testing. + public class NetObjectList : NetList { } +} diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs index e0f0e30c..54e91682 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs @@ -1,11 +1,20 @@ // ReSharper disable CheckNamespace, InconsistentNaming -- matches Stardew Valley's code +#pragma warning disable 649 // (never assigned) -- only used to test type conversions using System.Collections.Generic; +using Netcode; namespace StardewValley { /// A simplified version of Stardew Valley's StardewValley.Farmer class for unit testing. internal class Farmer { - public IDictionary friendships; + /// A sample field which should be replaced with a different property. + public readonly IDictionary friendships; + + /// A sample net list. + public readonly NetList eventsSeen; + + /// A sample net object list. + public readonly NetObjectList netObjectList; } } -- cgit From 1848abe7d57e32207db9535c9c83d96dbda64ced Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 14 Apr 2018 20:14:31 -0400 Subject: don't warn for NetCollection conversion to implemented interface (#471) --- .../Mock/Netcode/NetCollection.cs | 10 ++++++++++ .../Mock/StardewValley/Farmer.cs | 7 ------- .../Mock/StardewValley/Item.cs | 9 +++++++++ .../NetFieldAnalyzerTests.cs | 12 +++++++----- src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs | 11 +++++++++++ 5 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetCollection.cs (limited to 'src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock') diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetCollection.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetCollection.cs new file mode 100644 index 00000000..d160610e --- /dev/null +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetCollection.cs @@ -0,0 +1,10 @@ +// ReSharper disable CheckNamespace -- matches Stardew Valley's code +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace Netcode +{ + /// A simplified version of Stardew Valley's Netcode.NetCollection for unit testing. + public class NetCollection : Collection, IList, ICollection, IEnumerable, IEnumerable { } +} diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs index 54e91682..13fab069 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs @@ -1,7 +1,6 @@ // ReSharper disable CheckNamespace, InconsistentNaming -- matches Stardew Valley's code #pragma warning disable 649 // (never assigned) -- only used to test type conversions using System.Collections.Generic; -using Netcode; namespace StardewValley { @@ -10,11 +9,5 @@ namespace StardewValley { /// A sample field which should be replaced with a different property. public readonly IDictionary friendships; - - /// A sample net list. - public readonly NetList eventsSeen; - - /// A sample net object list. - public readonly NetObjectList netObjectList; } } diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Item.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Item.cs index 386767d7..1b6317c1 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Item.cs +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Item.cs @@ -20,5 +20,14 @@ namespace StardewValley /// A generic net ref property with no equivalent non-net property. public NetRef netRefProperty { get; } = new NetRef(); + + /// A sample net list. + public readonly NetList netList = new NetList(); + + /// A sample net object list. + public readonly NetObjectList netObjectList = new NetObjectList(); + + /// A sample net collection. + public readonly NetCollection netCollection = new NetCollection(); } } diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs index 15bcadcd..7b410085 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs @@ -86,7 +86,8 @@ namespace SMAPI.ModBuildConfig.Analyzer.Tests [TestCase("SObject obj = null; if (obj.netRefField != null);", 24, "obj.netRefField", "NetRef", "object")] [TestCase("SObject obj = null; if (obj.netRefProperty == null);", 24, "obj.netRefProperty", "NetRef", "object")] [TestCase("SObject obj = null; if (obj.netRefProperty != null);", 24, "obj.netRefProperty", "NetRef", "object")] - [TestCase("SFarmer farmer = new SFarmer(); object list = farmer.eventsSeen;", 46, "farmer.eventsSeen", "NetList", "object")] // ↓ NetList field converted to a non-interface type + [TestCase("Item item = new Item(); object list = item.netList;", 38, "item.netList", "NetList", "object")] // ↓ NetList field converted to a non-interface type + [TestCase("Item item = new Item(); object list = item.netCollection;", 38, "item.netCollection", "NetCollection", "object")] public void AvoidImplicitNetFieldComparisons_RaisesDiagnostic(string codeText, int column, string expression, string fromType, string toType) { // arrange @@ -105,10 +106,11 @@ namespace SMAPI.ModBuildConfig.Analyzer.Tests /// Test that the net field analyzer doesn't raise any warnings for safe member access. /// The code line to test. - [TestCase("SFarmer farmer = new SFarmer(); System.Collections.IEnumerable list = farmer.eventsSeen;")] - [TestCase("SFarmer farmer = new SFarmer(); System.Collections.Generic.IEnumerable list = farmer.eventsSeen;")] - [TestCase("SFarmer farmer = new SFarmer(); System.Collections.Generic.IList list = farmer.eventsSeen;")] - [TestCase("SFarmer farmer = new SFarmer(); System.Collections.Generic.IList list = farmer.netObjectList;")] // subclass of NetList + [TestCase("Item item = new Item(); System.Collections.IEnumerable list = farmer.eventsSeen;")] + [TestCase("Item item = new Item(); System.Collections.Generic.IEnumerable list = farmer.netList;")] + [TestCase("Item item = new Item(); System.Collections.Generic.IList list = farmer.netList;")] + [TestCase("Item item = new Item(); System.Collections.Generic.ICollection list = farmer.netCollection;")] + [TestCase("Item item = new Item(); System.Collections.Generic.IList list = farmer.netObjectList;")] // subclass of NetList public void AvoidImplicitNetFieldComparisons_AllowsSafeAccess(string codeText) { // arrange diff --git a/src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs b/src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs index 7c8b804e..72d3bbf8 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs +++ b/src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs @@ -22,6 +22,9 @@ namespace StardewModdingAPI.ModBuildConfig.Analyzer /// The full name for Stardew Valley's Netcode.NetList type. private readonly string NetListTypeFullName = "Netcode.NetList"; + /// The full name for Stardew Valley's Netcode.NetCollection type. + private readonly string NetCollectionTypeFullName = "Netcode.NetCollection"; + /// Maps net fields to their equivalent non-net properties where available. private readonly IDictionary NetFieldWrapperProperties = new Dictionary { @@ -232,6 +235,14 @@ namespace StardewModdingAPI.ModBuildConfig.Analyzer return false; } + // collection conversion to an implemented interface is OK + if (AnalyzerUtilities.GetConcreteTypes(typeInfo.Type).Any(p => p.ToString().StartsWith(this.NetCollectionTypeFullName))) // StartsWith to ignore generics + { + string toType = typeInfo.ConvertedType.ToString(); + if (toType.StartsWith(typeof(IEnumerable<>).Namespace) || toType == typeof(IEnumerable).FullName) + return false; + } + // avoid any other conversions return true; } -- cgit