Skip to content

Commit

Permalink
[GH-76] - removing code duplication for finding substitution node
Browse files Browse the repository at this point in the history
  • Loading branch information
tpodolak committed Apr 3, 2019
1 parent 0929c58 commit 2382032
Show file tree
Hide file tree
Showing 22 changed files with 91 additions and 127 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace NSubstitute.Analyzers.CSharp.DiagnosticAnalyzers
internal class CallInfoAnalyzer : AbstractCallInfoAnalyzer<SyntaxKind, InvocationExpressionSyntax, ExpressionSyntax, ElementAccessExpressionSyntax>
{
public CallInfoAnalyzer()
: base(new DiagnosticDescriptorsProvider())
: base(new DiagnosticDescriptorsProvider(), new CallInfoCallFinder(), new SubstitutionNodeFinder())
{
}

Expand All @@ -24,16 +24,6 @@ protected override IEnumerable<ExpressionSyntax> GetArgumentExpressions(Invocati
return invocationExpressionSyntax.ArgumentList.Arguments.Select(arg => arg.Expression);
}

protected override AbstractCallInfoFinder<InvocationExpressionSyntax, ElementAccessExpressionSyntax> GetCallInfoFinder()
{
return new CallInfoCallFinder();
}

protected override AbstractSubstitutionNodeFinder<InvocationExpressionSyntax> GetSubstitutionNodeFinder()
{
return new SubstitutionNodeFinder();
}

protected override SyntaxNode GetCastTypeExpression(ElementAccessExpressionSyntax indexerExpressionSyntax)
{
switch (indexerExpressionSyntax.Parent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

namespace NSubstitute.Analyzers.CSharp.DiagnosticAnalyzers
{
internal class CallInfoCallFinder : AbstractCallInfoFinder<InvocationExpressionSyntax, ElementAccessExpressionSyntax>
internal class CallInfoCallFinder : ICallInfoFinder<InvocationExpressionSyntax, ElementAccessExpressionSyntax>
{
public override CallInfoContext<InvocationExpressionSyntax, ElementAccessExpressionSyntax> GetCallInfoContext(SemanticModel semanticModel, SyntaxNode syntaxNode)
public CallInfoContext<InvocationExpressionSyntax, ElementAccessExpressionSyntax> GetCallInfoContext(SemanticModel semanticModel, SyntaxNode syntaxNode)
{
var visitor = new CallInfoVisitor(semanticModel);
visitor.Visit(syntaxNode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace NSubstitute.Analyzers.CSharp.DiagnosticAnalyzers
internal class ConflictingArgumentAssignmentsAnalyzer : AbstractConflictingArgumentAssignmentsAnalyzer<SyntaxKind, InvocationExpressionSyntax, ExpressionSyntax, ElementAccessExpressionSyntax>
{
public ConflictingArgumentAssignmentsAnalyzer()
: base(new DiagnosticDescriptorsProvider())
: base(new DiagnosticDescriptorsProvider(), new CallInfoCallFinder())
{
}

Expand All @@ -30,11 +30,6 @@ protected override SyntaxNode GetSubstituteCall(SyntaxNodeAnalysisContext syntax
return invocationExpressionSyntax.GetParentInvocationExpression();
}

protected override AbstractCallInfoFinder<InvocationExpressionSyntax, ElementAccessExpressionSyntax> GetCallInfoFinder()
{
return new CallInfoCallFinder();
}

protected override int? GetIndexerPosition(SyntaxNodeAnalysisContext syntaxNodeAnalysisContext, ElementAccessExpressionSyntax indexerExpressionSyntax)
{
var position = syntaxNodeAnalysisContext.SemanticModel.GetConstantValue(indexerExpressionSyntax.ArgumentList.Arguments.First().Expression);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,10 @@ namespace NSubstitute.Analyzers.CSharp.DiagnosticAnalyzers
internal class NonSubstitutableMemberWhenAnalyzer : AbstractNonSubstitutableMemberWhenAnalyzer<SyntaxKind, InvocationExpressionSyntax>
{
public NonSubstitutableMemberWhenAnalyzer()
: base(new DiagnosticDescriptorsProvider())
: base(new DiagnosticDescriptorsProvider(), new SubstitutionNodeFinder())
{
}

protected override SyntaxKind InvocationExpressionKind { get; } = SyntaxKind.InvocationExpression;

protected override AbstractSubstitutionNodeFinder<InvocationExpressionSyntax> GetSubstitutionNodeFinder()
{
return new SubstitutionNodeFinder();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,10 @@ namespace NSubstitute.Analyzers.CSharp.DiagnosticAnalyzers
internal class ReEntrantSetupAnalyzer : AbstractReEntrantSetupAnalyzer<SyntaxKind, InvocationExpressionSyntax>
{
public ReEntrantSetupAnalyzer()
: base(new DiagnosticDescriptorsProvider())
: base(new DiagnosticDescriptorsProvider(), new ReEntrantCallFinder())
{
}

protected override AbstractReEntrantCallFinder GetReEntrantCallFinder()
{
return new ReEntrantCallFinder();
}

protected override SyntaxKind InvocationExpressionKind { get; } = SyntaxKind.InvocationExpression;

protected override IEnumerable<SyntaxNode> ExtractArguments(InvocationExpressionSyntax invocationExpressionSyntax)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,7 @@ public override SyntaxNode FindForAndDoesExpression(SyntaxNodeAnalysisContext sy
: parentInvocationExpression.Expression.DescendantNodes().First();
}

protected override InvocationExpressionSyntax GetParentInvocationExpression(InvocationExpressionSyntax invocationExpressionSyntax)
{
return invocationExpressionSyntax.GetParentInvocationExpression();
}

protected override SyntaxNode FindForStandardSubstitution(InvocationExpressionSyntax invocationExpressionSyntax, IMethodSymbol invocationExpressionSymbol)
public override SyntaxNode FindForStandardExpression(InvocationExpressionSyntax invocationExpressionSyntax, IMethodSymbol invocationExpressionSymbol)
{
switch (invocationExpressionSymbol.MethodKind)
{
Expand All @@ -69,6 +64,11 @@ protected override SyntaxNode FindForStandardSubstitution(InvocationExpressionSy
}
}

protected override InvocationExpressionSyntax GetParentInvocationExpression(InvocationExpressionSyntax invocationExpressionSyntax)
{
return invocationExpressionSyntax.GetParentInvocationExpression();
}

private IEnumerable<SyntaxNode> FindForWhenExpression(SyntaxNodeAnalysisContext syntaxNodeContext, SyntaxNode argumentSyntax)
{
SyntaxNode body = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,17 @@ internal abstract class AbstractCallInfoAnalyzer<TSyntaxKind, TInvocationExpress
where TIndexerExpressionSyntax : SyntaxNode
where TSyntaxKind : struct
{
private readonly Lazy<AbstractCallInfoFinder<TInvocationExpressionSyntax, TIndexerExpressionSyntax>> _callInfoFinderProxy;
private readonly ICallInfoFinder<TInvocationExpressionSyntax, TIndexerExpressionSyntax> _callInfoFinder;
private readonly ISubstitutionNodeFinder<TInvocationExpressionSyntax> _substitutionNodeFinder;

private readonly Lazy<AbstractSubstitutionNodeFinder<TInvocationExpressionSyntax>> _substitutionNodeFinderProxy;

private AbstractCallInfoFinder<TInvocationExpressionSyntax, TIndexerExpressionSyntax> CallInfoFinder => _callInfoFinderProxy.Value;

private AbstractSubstitutionNodeFinder<TInvocationExpressionSyntax> SubstitutionNodeFinder => _substitutionNodeFinderProxy.Value;

protected AbstractCallInfoAnalyzer(IDiagnosticDescriptorsProvider diagnosticDescriptorsProvider)
protected AbstractCallInfoAnalyzer(
IDiagnosticDescriptorsProvider diagnosticDescriptorsProvider,
ICallInfoFinder<TInvocationExpressionSyntax, TIndexerExpressionSyntax> callInfoFinder,
ISubstitutionNodeFinder<TInvocationExpressionSyntax> substitutionNodeFinder)
: base(diagnosticDescriptorsProvider)
{
_callInfoFinderProxy = new Lazy<AbstractCallInfoFinder<TInvocationExpressionSyntax, TIndexerExpressionSyntax>>(GetCallInfoFinder);
_substitutionNodeFinderProxy = new Lazy<AbstractSubstitutionNodeFinder<TInvocationExpressionSyntax>>(GetSubstitutionNodeFinder);
_callInfoFinder = callInfoFinder;
_substitutionNodeFinder = substitutionNodeFinder;
}

private static readonly ImmutableDictionary<string, string> MethodNames = new Dictionary<string, string>()
Expand Down Expand Up @@ -56,10 +54,6 @@ public override void Initialize(AnalysisContext context)

protected abstract IEnumerable<TExpressionSyntax> GetArgumentExpressions(TInvocationExpressionSyntax invocationExpressionSyntax);

protected abstract AbstractCallInfoFinder<TInvocationExpressionSyntax, TIndexerExpressionSyntax> GetCallInfoFinder();

protected abstract AbstractSubstitutionNodeFinder<TInvocationExpressionSyntax> GetSubstitutionNodeFinder();

protected abstract SyntaxNode GetCastTypeExpression(TIndexerExpressionSyntax indexerExpressionSyntax);

protected abstract SyntaxNode GetAssignmentExpression(TIndexerExpressionSyntax indexerExpressionSyntax);
Expand Down Expand Up @@ -130,7 +124,7 @@ private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext)

foreach (var argumentExpressionSyntax in GetArgumentExpressions(invocationExpression))
{
var callInfoContext = CallInfoFinder.GetCallInfoContext(syntaxNodeContext.SemanticModel, argumentExpressionSyntax);
var callInfoContext = _callInfoFinder.GetCallInfoContext(syntaxNodeContext.SemanticModel, argumentExpressionSyntax);

AnalyzeArgAtInvocations(syntaxNodeContext, callInfoContext, substituteCallParameters);

Expand Down Expand Up @@ -303,7 +297,7 @@ private bool AnalyzeAssignment(SyntaxNodeAnalysisContext syntaxNodeContext, ILis

private IList<IParameterSymbol> GetSubstituteCallParameters(SyntaxNodeAnalysisContext syntaxNodeContext, IMethodSymbol methodSymbol, TInvocationExpressionSyntax invocationExpression)
{
var parentMethodCallSyntax = SubstitutionNodeFinder.Find(syntaxNodeContext, invocationExpression, methodSymbol).FirstOrDefault();
var parentMethodCallSyntax = _substitutionNodeFinder.Find(syntaxNodeContext, invocationExpression, methodSymbol).FirstOrDefault();

if (parentMethodCallSyntax == null)
{
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ internal abstract class AbstractConflictingArgumentAssignmentsAnalyzer<TSyntaxKi
where TIndexerExpressionSyntax : SyntaxNode
where TSyntaxKind : struct
{
protected AbstractConflictingArgumentAssignmentsAnalyzer(IDiagnosticDescriptorsProvider diagnosticDescriptorsProvider)
private readonly ICallInfoFinder<TInvocationExpressionSyntax, TIndexerExpressionSyntax> _callInfoFinder;

protected AbstractConflictingArgumentAssignmentsAnalyzer(IDiagnosticDescriptorsProvider diagnosticDescriptorsProvider, ICallInfoFinder<TInvocationExpressionSyntax, TIndexerExpressionSyntax> callInfoFinder)
: base(diagnosticDescriptorsProvider)
{
_callInfoFinder = callInfoFinder;
SupportedDiagnostics = ImmutableArray.Create(DiagnosticDescriptorsProvider.ConflictingArgumentAssignments);
}

Expand All @@ -38,8 +41,6 @@ public override void Initialize(AnalysisContext context)

protected abstract SyntaxNode GetSubstituteCall(SyntaxNodeAnalysisContext syntaxNodeContext, IMethodSymbol methodSymbol, TInvocationExpressionSyntax invocationExpressionSyntax);

protected abstract AbstractCallInfoFinder<TInvocationExpressionSyntax, TIndexerExpressionSyntax> GetCallInfoFinder();

protected abstract int? GetIndexerPosition(SyntaxNodeAnalysisContext syntaxNodeAnalysisContext, TIndexerExpressionSyntax indexerExpressionSyntax);

protected abstract ISymbol GetIndexerSymbol(SyntaxNodeAnalysisContext syntaxNodeAnalysisContext, TIndexerExpressionSyntax indexerExpressionSyntax);
Expand Down Expand Up @@ -110,7 +111,7 @@ private bool IsAssigned(SyntaxNodeAnalysisContext syntaxNodeAnalysisContext, TIn

private IEnumerable<TIndexerExpressionSyntax> FindCallInfoIndexers(SyntaxNodeAnalysisContext syntaxNodeContext, TInvocationExpressionSyntax invocationExpressionSyntax)
{
return GetArgumentExpressions(invocationExpressionSyntax).SelectMany(argument => GetCallInfoFinder().GetCallInfoContext(syntaxNodeContext.SemanticModel, argument).IndexerAccesses)
return GetArgumentExpressions(invocationExpressionSyntax).SelectMany(argument => _callInfoFinder.GetCallInfoContext(syntaxNodeContext.SemanticModel, argument).IndexerAccesses)
.Where(indexerExpression => IsAssigned(syntaxNodeContext, indexerExpression));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ internal abstract class AbstractNonSubstitutableMemberWhenAnalyzer<TSyntaxKind,
where TInvocationExpressionSyntax : SyntaxNode
where TSyntaxKind : struct
{
private readonly ISubstitutionNodeFinder<TInvocationExpressionSyntax> _substitutionNodeFinder;

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(
DiagnosticDescriptorsProvider.NonVirtualWhenSetupSpecification,
DiagnosticDescriptorsProvider.InternalSetupSpecification);
Expand All @@ -22,23 +24,17 @@ internal abstract class AbstractNonSubstitutableMemberWhenAnalyzer<TSyntaxKind,

protected abstract TSyntaxKind InvocationExpressionKind { get; }

private readonly Lazy<AbstractSubstitutionNodeFinder<TInvocationExpressionSyntax>> _substitutionNodeFinderProxy;

private AbstractSubstitutionNodeFinder<TInvocationExpressionSyntax> SubstitutionNodeFinderProxy => _substitutionNodeFinderProxy.Value;

protected AbstractNonSubstitutableMemberWhenAnalyzer(IDiagnosticDescriptorsProvider diagnosticDescriptorsProvider)
protected AbstractNonSubstitutableMemberWhenAnalyzer(IDiagnosticDescriptorsProvider diagnosticDescriptorsProvider, ISubstitutionNodeFinder<TInvocationExpressionSyntax> substitutionNodeFinder)
: base(diagnosticDescriptorsProvider)
{
_substitutionNodeFinderProxy = new Lazy<AbstractSubstitutionNodeFinder<TInvocationExpressionSyntax>>(GetSubstitutionNodeFinder);
_substitutionNodeFinder = substitutionNodeFinder;
}

public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(AnalyzeInvocation, InvocationExpressionKind);
}

protected abstract AbstractSubstitutionNodeFinder<TInvocationExpressionSyntax> GetSubstitutionNodeFinder();

private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext)
{
var invocationExpression = (TInvocationExpressionSyntax)syntaxNodeContext.Node;
Expand All @@ -60,7 +56,7 @@ private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext)
return;
}

var expressionsForAnalysys = SubstitutionNodeFinderProxy.FindForWhenExpression(syntaxNodeContext, invocationExpression, methodSymbol);
var expressionsForAnalysys = _substitutionNodeFinder.FindForWhenExpression(syntaxNodeContext, invocationExpression, methodSymbol);
var typeSymbol = methodSymbol.TypeArguments.FirstOrDefault() ?? methodSymbol.ReceiverType;
foreach (var analysedSyntax in expressionsForAnalysys)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace NSubstitute.Analyzers.Shared.DiagnosticAnalyzers
{
internal abstract class AbstractReEntrantCallFinder
internal abstract class AbstractReEntrantCallFinder : IReEntrantCallFinder
{
private static readonly ImmutableDictionary<string, string> MethodNames = new Dictionary<string, string>()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,21 @@ internal abstract class AbstractReEntrantSetupAnalyzer<TSyntaxKind, TInvocationE
where TInvocationExpressionSyntax : SyntaxNode
where TSyntaxKind : struct
{
private readonly IReEntrantCallFinder _reEntrantCallFinder;

private static readonly ImmutableHashSet<string> MethodNames = ImmutableHashSet.Create(
MetadataNames.NSubstituteReturnsMethod,
MetadataNames.NSubstituteReturnsForAnyArgsMethod);

private AbstractReEntrantCallFinder ReEntrantCallFinder => _reEntrantCallFinderProxy.Value;

private readonly Lazy<AbstractReEntrantCallFinder> _reEntrantCallFinderProxy;

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
ImmutableArray.Create(DiagnosticDescriptorsProvider.ReEntrantSubstituteCall);

protected AbstractReEntrantSetupAnalyzer(IDiagnosticDescriptorsProvider diagnosticDescriptorsProvider)
protected AbstractReEntrantSetupAnalyzer(IDiagnosticDescriptorsProvider diagnosticDescriptorsProvider, IReEntrantCallFinder reEntrantCallFinder)
: base(diagnosticDescriptorsProvider)
{
_reEntrantCallFinderProxy = new Lazy<AbstractReEntrantCallFinder>(GetReEntrantCallFinder);
_reEntrantCallFinder = reEntrantCallFinder;
}

protected abstract AbstractReEntrantCallFinder GetReEntrantCallFinder();

protected abstract TSyntaxKind InvocationExpressionKind { get; }

public override void Initialize(AnalysisContext context)
Expand Down Expand Up @@ -61,7 +57,7 @@ private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext)

foreach (var argument in argumentsForAnalysis)
{
var reentrantSymbol = ReEntrantCallFinder.GetReEntrantCalls(syntaxNodeContext.Compilation, argument).FirstOrDefault();
var reentrantSymbol = _reEntrantCallFinder.GetReEntrantCalls(syntaxNodeContext.Compilation, argument).FirstOrDefault();
if (reentrantSymbol != null)
{
var diagnostic = Diagnostic.Create(
Expand Down
Loading

0 comments on commit 2382032

Please sign in to comment.