summaryrefslogtreecommitdiff
path: root/src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <github@jplamondonw.com>2018-04-14 19:51:50 -0400
committerJesse Plamondon-Willard <github@jplamondonw.com>2018-04-14 19:51:50 -0400
commit6d8cf614a24ab69baffa89c351b9a22776741442 (patch)
tree6e07d08270b478d4f7596d5cea9a525621fdab7b /src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs
parentc2cb76b79919261c4d7eab107c5cb77ec6c6a81c (diff)
downloadSMAPI-6d8cf614a24ab69baffa89c351b9a22776741442.tar.gz
SMAPI-6d8cf614a24ab69baffa89c351b9a22776741442.tar.bz2
SMAPI-6d8cf614a24ab69baffa89c351b9a22776741442.zip
don't warn for NetList conversion to implemented interface (#471)
Diffstat (limited to 'src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs')
-rw-r--r--src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs30
1 files changed, 27 insertions, 3 deletions
diff --git a/src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs b/src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs
index 895eebf0..7c8b804e 100644
--- a/src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs
+++ b/src/SMAPI.ModBuildConfig.Analyzer/NetFieldAnalyzer.cs
@@ -1,6 +1,8 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
+using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
@@ -17,6 +19,9 @@ namespace StardewModdingAPI.ModBuildConfig.Analyzer
/// <summary>The namespace for Stardew Valley's <c>Netcode</c> types.</summary>
private const string NetcodeNamespace = "Netcode";
+ /// <summary>The full name for Stardew Valley's <c>Netcode.NetList</c> type.</summary>
+ private readonly string NetListTypeFullName = "Netcode.NetList";
+
/// <summary>Maps net fields to their equivalent non-net properties where available.</summary>
private readonly IDictionary<string, string> NetFieldWrapperProperties = new Dictionary<string, string>
{
@@ -190,10 +195,9 @@ namespace StardewModdingAPI.ModBuildConfig.Analyzer
return;
if (!this.IsNetType(memberType.Type))
return;
- bool isConverted = !this.IsNetType(memberType.ConvertedType);
// warn: use property wrapper if available
- for (ITypeSymbol type = declaringType; type != null; type = type.BaseType)
+ foreach (ITypeSymbol type in AnalyzerUtilities.GetConcreteTypes(declaringType))
{
if (this.NetFieldWrapperProperties.TryGetValue($"{type}::{memberName}", out string suggestedPropertyName))
{
@@ -203,7 +207,7 @@ namespace StardewModdingAPI.ModBuildConfig.Analyzer
}
// warn: implicit conversion
- if (isConverted)
+ if (this.IsInvalidConversion(memberType))
context.ReportDiagnostic(Diagnostic.Create(this.Rules["AvoidImplicitNetFieldCast"], context.Node.GetLocation(), context.Node, memberType.Type.Name, memberType.ConvertedType));
}
catch (Exception ex)
@@ -212,6 +216,26 @@ namespace StardewModdingAPI.ModBuildConfig.Analyzer
}
}
+ /// <summary>Get whether a net field was converted in an error-prone way.</summary>
+ /// <param name="typeInfo">The member access type info.</param>
+ private bool IsInvalidConversion(TypeInfo typeInfo)
+ {
+ // no conversion
+ if (!this.IsNetType(typeInfo.Type) || this.IsNetType(typeInfo.ConvertedType))
+ return false;
+
+ // list conversion to an implemented interface is OK
+ if (AnalyzerUtilities.GetConcreteTypes(typeInfo.Type).Any(p => p.ToString().StartsWith(this.NetListTypeFullName))) // 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;
+ }
+
/// <summary>Get whether a type symbol references a <c>Netcode</c> type.</summary>
/// <param name="typeSymbol">The type symbol.</param>
private bool IsNetType(ITypeSymbol typeSymbol)