Skip to content

Commit d0d1959

Browse files
authored
further check invocation symbol (#82)
* further check invocation symbol - check if symbol is method - check if multiple candidate symbols are found * fix NullReference
1 parent 6668b28 commit d0d1959

File tree

3 files changed

+55
-4
lines changed

3 files changed

+55
-4
lines changed

System.IO.Abstractions.Analyzers.Tests/Analyzers/PathAnalyzerTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class PathAnalyzerTests : CSharpDiagnosticAnalyzerTest<PathAnalyzer>
1212
[Theory]
1313
[InlineData("Valid.txt")]
1414
[InlineData("UsingStaticFalsePositive.txt")]
15+
[InlineData("UsingStaticLinqFalsePositive.txt")]
1516
public void Analyzer_is_not_triggered(string filename)
1617
{
1718
var source = ReadFile(filename);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace SomeNameSpace.Mocking
2+
{
3+
using System.IO.Abstractions;
4+
public static class FileSystemProxy
5+
{
6+
internal static IPath Path { get; }
7+
}
8+
}
9+
10+
namespace SomeNameSpace
11+
{
12+
using System.Collections.Generic;
13+
using System.Linq;
14+
using static SomeNameSpace.Mocking.FileSystemProxy;
15+
public class UsingStaticFalsePositive
16+
{
17+
private IList<string> files;
18+
public UsingStaticFalsePositive()
19+
{
20+
}
21+
22+
public void SomeMethod()
23+
{
24+
var x = files
25+
.First(item => Path.GetFileName(item)
26+
.Equals("Pattern.txt", StringComparison.OrdinalIgnoreCase));
27+
}
28+
}
29+
}

System.IO.Abstractions.Analyzers/Analyzers/BaseFileSystemNodeAnalyzer.cs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Linq;
12
using Microsoft.CodeAnalysis;
23
using Microsoft.CodeAnalysis.CSharp;
34
using Microsoft.CodeAnalysis.CSharp.Syntax;
@@ -69,10 +70,30 @@ private bool IsStaticInvocationStartWith(InvocationExpressionSyntax invocation)
6970
private static bool IsInvocationFromAbstractions(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocation)
7071
{
7172
return (invocation?.Expression as MemberAccessExpressionSyntax)?.Expression is ExpressionSyntax invokedMember
72-
&& context.SemanticModel.GetSymbolInfo(invokedMember).Symbol is ISymbol symbol
73-
&& ((symbol as IPropertySymbol)?.Type ?? (symbol as IFieldSymbol)?.Type) is ITypeSymbol type
74-
&& !type.ContainingNamespace.IsGlobalNamespace
75-
&& type.ContainingNamespace.ToString().StartsWith(Constants.FileSystemNameSpace, StringComparison.Ordinal);
73+
&& IsSymbolFromAbstractions(context.SemanticModel.GetSymbolInfo(invokedMember));
74+
}
75+
76+
private static bool IsSymbolFromAbstractions(SymbolInfo symbolInfo)
77+
{
78+
if (symbolInfo.Symbol is ISymbol symbol)
79+
{
80+
return IsSymbolFromAbstractions(symbol);
81+
} else if (symbolInfo.CandidateSymbols.Length > 0)
82+
{
83+
return symbolInfo.CandidateSymbols.All(IsSymbolFromAbstractions);
84+
}
85+
return false;
86+
}
87+
88+
private static bool IsSymbolFromAbstractions(ISymbol symbol)
89+
{
90+
INamespaceSymbol namespaceSymbol
91+
= ((symbol as IPropertySymbol)?.Type ?? (symbol as IFieldSymbol)?.Type)?.ContainingNamespace
92+
?? (symbol as IMethodSymbol)?.ContainingNamespace;
93+
94+
return namespaceSymbol != null
95+
&& !namespaceSymbol.IsGlobalNamespace
96+
&& namespaceSymbol.ToString().StartsWith(Constants.FileSystemNameSpace, StringComparison.Ordinal);
7697
}
7798
}
7899
}

0 commit comments

Comments
 (0)