diff --git a/src/FluentAssertions.Analyzers.Tests/Tips/SanityTests.cs b/src/FluentAssertions.Analyzers.Tests/Tips/SanityTests.cs index 443df1c7..ae5b2933 100644 --- a/src/FluentAssertions.Analyzers.Tests/Tips/SanityTests.cs +++ b/src/FluentAssertions.Analyzers.Tests/Tips/SanityTests.cs @@ -160,5 +160,34 @@ public void StringShouldNotBeEmptyAndShouldNotBeNull_ShouldNotTrigger() DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source); } + + [TestMethod] + [Implemented(Reason = "https://github.com/fluentassertions/fluentassertions.analyzers/issues/65")] + public void CustomClass_ShouldNotTrigger_DictionaryAnalyzers() + { + const string source = @" +using System.Linq; +using FluentAssertions; +using FluentAssertions.Extensions; + +namespace TestNamespace +{ + class MyDict + { + public bool ContainsKey(TKey key) => false; + } + + public class Program + { + public static void Main() + { + var dict = new MyDict(); + dict.ContainsKey(0).Should().BeTrue(); + } + } +}"; + + DiagnosticVerifier.VerifyCSharpDiagnosticUsingAllAnalyzers(source); + } } } \ No newline at end of file diff --git a/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryAnalyzer.cs b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryAnalyzer.cs new file mode 100644 index 00000000..910c5b06 --- /dev/null +++ b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryAnalyzer.cs @@ -0,0 +1,11 @@ +using System.Linq; +using Microsoft.CodeAnalysis; + +namespace FluentAssertions.Analyzers +{ + public abstract class DictionaryAnalyzer : FluentAssertionsAnalyzer + { + protected override bool ShouldAnalyzeVariableType(ITypeSymbol type) + => type.AllInterfaces.Any(@interface => @interface.Name == "IDictionary"); + } +} \ No newline at end of file diff --git a/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainKey.cs b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainKey.cs index 4f52e8c6..12bffffe 100644 --- a/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainKey.cs +++ b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainKey.cs @@ -9,7 +9,7 @@ namespace FluentAssertions.Analyzers { [DiagnosticAnalyzer(LanguageNames.CSharp)] - public class DictionaryShouldContainKeyAnalyzer : FluentAssertionsAnalyzer + public class DictionaryShouldContainKeyAnalyzer : DictionaryAnalyzer { public const string DiagnosticId = Constants.Tips.Dictionaries.DictionaryShouldContainKey; public const string Category = Constants.Tips.Category; diff --git a/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainKeyAndValue.cs b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainKeyAndValue.cs index 75a64b3e..e4f4a48c 100644 --- a/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainKeyAndValue.cs +++ b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainKeyAndValue.cs @@ -10,7 +10,7 @@ namespace FluentAssertions.Analyzers { [DiagnosticAnalyzer(LanguageNames.CSharp)] - public class DictionaryShouldContainKeyAndValueAnalyzer : FluentAssertionsAnalyzer + public class DictionaryShouldContainKeyAndValueAnalyzer : DictionaryAnalyzer { public const string DiagnosticId = Constants.Tips.Dictionaries.DictionaryShouldContainKeyAndValue; public const string Category = Constants.Tips.Category; diff --git a/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainPair.cs b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainPair.cs index cd0ab10c..1b909307 100644 --- a/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainPair.cs +++ b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainPair.cs @@ -10,7 +10,7 @@ namespace FluentAssertions.Analyzers { [DiagnosticAnalyzer(LanguageNames.CSharp)] - public class DictionaryShouldContainPairAnalyzer : FluentAssertionsAnalyzer + public class DictionaryShouldContainPairAnalyzer : DictionaryAnalyzer { public const string DiagnosticId = Constants.Tips.Dictionaries.DictionaryShouldContainPair; public const string Category = Constants.Tips.Category; diff --git a/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainValue.cs b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainValue.cs index e0061bb2..eac96ec3 100644 --- a/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainValue.cs +++ b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldContainValue.cs @@ -9,7 +9,7 @@ namespace FluentAssertions.Analyzers { [DiagnosticAnalyzer(LanguageNames.CSharp)] - public class DictionaryShouldContainValueAnalyzer : FluentAssertionsAnalyzer + public class DictionaryShouldContainValueAnalyzer : DictionaryAnalyzer { public const string DiagnosticId = Constants.Tips.Dictionaries.DictionaryShouldContainValue; public const string Category = Constants.Tips.Category; diff --git a/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldNotContainKey.cs b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldNotContainKey.cs index 19bfe69d..f09275fb 100644 --- a/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldNotContainKey.cs +++ b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldNotContainKey.cs @@ -9,7 +9,7 @@ namespace FluentAssertions.Analyzers { [DiagnosticAnalyzer(LanguageNames.CSharp)] - public class DictionaryShouldNotContainKeyAnalyzer : FluentAssertionsAnalyzer + public class DictionaryShouldNotContainKeyAnalyzer : DictionaryAnalyzer { public const string DiagnosticId = Constants.Tips.Dictionaries.DictionaryShouldNotContainKey; public const string Category = Constants.Tips.Category; diff --git a/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldNotContainValue.cs b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldNotContainValue.cs index b7e388e8..421ac5bf 100644 --- a/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldNotContainValue.cs +++ b/src/FluentAssertions.Analyzers/Tips/Dictionaries/DictionaryShouldNotContainValue.cs @@ -9,7 +9,7 @@ namespace FluentAssertions.Analyzers { [DiagnosticAnalyzer(LanguageNames.CSharp)] - public class DictionaryShouldNotContainValueAnalyzer : FluentAssertionsAnalyzer + public class DictionaryShouldNotContainValueAnalyzer : DictionaryAnalyzer { public const string DiagnosticId = Constants.Tips.Dictionaries.DictionaryShouldNotContainValue; public const string Category = Constants.Tips.Category; diff --git a/src/FluentAssertions.Analyzers/Utilities/FluentAssertionsAnalyzer.cs b/src/FluentAssertions.Analyzers/Utilities/FluentAssertionsAnalyzer.cs index 7a84bb51..4ab1e79f 100644 --- a/src/FluentAssertions.Analyzers/Utilities/FluentAssertionsAnalyzer.cs +++ b/src/FluentAssertions.Analyzers/Utilities/FluentAssertionsAnalyzer.cs @@ -60,8 +60,8 @@ protected virtual Diagnostic AnalyzeExpression(ExpressionSyntax expression, Sema if (variableNameExtractor.VariableIdentifierName == null) return null; var typeInfo = semanticModel.GetTypeInfo(variableNameExtractor.VariableIdentifierName); - if (typeInfo.ConvertedType == null) return null; - if (!ShouldAnalyzeVariableType(typeInfo.ConvertedType)) return null; + if (typeInfo.Type == null) return null; + if (!ShouldAnalyzeVariableType(typeInfo.Type)) return null; foreach (var visitor in Visitors) {