Skip to content

Commit

Permalink
[GH-153] - simplifying SubstituteProxyAnalysis with operations api
Browse files Browse the repository at this point in the history
  • Loading branch information
tpodolak committed Dec 20, 2020
1 parent 5ee23f4 commit bd23284
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 64 deletions.
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "2.2.104"
"version": "3.1.201"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace NSubstitute.Analyzers.CSharp.CodeFixProviders
{
[ExportCodeFixProvider(LanguageNames.CSharp)]
internal sealed class SubstituteForInternalMemberCodeFixProvider : AbstractSubstituteForInternalMemberCodeFixProvider<InvocationExpressionSyntax, ExpressionSyntax, CompilationUnitSyntax>
internal sealed class SubstituteForInternalMemberCodeFixProvider : AbstractSubstituteForInternalMemberCodeFixProvider<InvocationExpressionSyntax, CompilationUnitSyntax>
{
public SubstituteForInternalMemberCodeFixProvider()
: base(SubstituteProxyAnalysis.Instance)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,14 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NSubstitute.Analyzers.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NSubstitute.Analyzers.Shared.DiagnosticAnalyzers;

namespace NSubstitute.Analyzers.CSharp.DiagnosticAnalyzers
{
internal class SubstituteProxyAnalysis : AbstractSubstituteProxyAnalysis<InvocationExpressionSyntax, ExpressionSyntax>
internal class SubstituteProxyAnalysis : AbstractSubstituteProxyAnalysis<InvocationExpressionSyntax>
{
public static SubstituteProxyAnalysis Instance { get; } = new SubstituteProxyAnalysis();

private SubstituteProxyAnalysis()
{
}

protected override IEnumerable<ExpressionSyntax> GetTypeOfLikeExpressions(IList<ExpressionSyntax> arrayParameters)
{
return arrayParameters.OfType<TypeOfExpressionSyntax>();
}

protected override IEnumerable<ExpressionSyntax> GetArrayInitializerArguments(InvocationExpressionSyntax invocationExpressionSyntax)
{
return invocationExpressionSyntax.ArgumentList?.Arguments.FirstOrDefault().Expression
.GetParameterExpressionsFromArrayArgument();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using NSubstitute.Analyzers.Shared.DiagnosticAnalyzers;

namespace NSubstitute.Analyzers.Shared.CodeFixProviders
{
internal abstract class AbstractSubstituteForInternalMemberCodeFixProvider<TInvocationExpressionSyntax, TExpressionSyntax, TCompilationUnitSyntax> : AbstractSuppressDiagnosticsCodeFixProvider
internal abstract class AbstractSubstituteForInternalMemberCodeFixProvider<TInvocationExpressionSyntax, TCompilationUnitSyntax> : AbstractSuppressDiagnosticsCodeFixProvider
where TInvocationExpressionSyntax : SyntaxNode
where TExpressionSyntax : SyntaxNode
where TCompilationUnitSyntax : SyntaxNode
{
private readonly ISubstituteProxyAnalysis<TInvocationExpressionSyntax, TExpressionSyntax> _substituteProxyAnalysis;
private readonly ISubstituteProxyAnalysis<TInvocationExpressionSyntax> _substituteProxyAnalysis;

public override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(DiagnosticIdentifiers.SubstituteForInternalMember);

protected AbstractSubstituteForInternalMemberCodeFixProvider(ISubstituteProxyAnalysis<TInvocationExpressionSyntax, TExpressionSyntax> substituteProxyAnalysis)
protected AbstractSubstituteForInternalMemberCodeFixProvider(ISubstituteProxyAnalysis<TInvocationExpressionSyntax> substituteProxyAnalysis)
{
_substituteProxyAnalysis = substituteProxyAnalysis;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ internal abstract class AbstractSubstituteAnalyzer<TSyntaxKind, TInvocationExpre
where TExpressionSyntax : SyntaxNode
where TArgumentSyntax : SyntaxNode
{
private readonly ISubstituteProxyAnalysis<TInvocationExpressionSyntax, TExpressionSyntax> _substituteProxyAnalysis;
private readonly ISubstituteProxyAnalysis<TInvocationExpressionSyntax> _substituteProxyAnalysis;
private readonly ISubstituteConstructorAnalysis<TInvocationExpressionSyntax> _substituteConstructorAnalysis;
private readonly ISubstituteConstructorMatcher _substituteConstructorMatcher;

private readonly Action<SyntaxNodeAnalysisContext> _analyzeInvocationAction;

protected AbstractSubstituteAnalyzer(
IDiagnosticDescriptorsProvider diagnosticDescriptorsProvider,
ISubstituteProxyAnalysis<TInvocationExpressionSyntax, TExpressionSyntax> substituteProxyAnalysis,
ISubstituteProxyAnalysis<TInvocationExpressionSyntax> substituteProxyAnalysis,
ISubstituteConstructorAnalysis<TInvocationExpressionSyntax> substituteConstructorAnalysis,
ISubstituteConstructorMatcher substituteConstructorMatcher)
: base(diagnosticDescriptorsProvider)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Operations;

namespace NSubstitute.Analyzers.Shared.DiagnosticAnalyzers
{
internal abstract class AbstractSubstituteProxyAnalysis<TInvocationExpressionSyntax, TExpressionSyntax> :
ISubstituteProxyAnalysis<TInvocationExpressionSyntax, TExpressionSyntax>
where TInvocationExpressionSyntax : SyntaxNode where TExpressionSyntax : SyntaxNode
internal abstract class AbstractSubstituteProxyAnalysis<TInvocationExpressionSyntax> : ISubstituteProxyAnalysis<TInvocationExpressionSyntax>
where TInvocationExpressionSyntax : SyntaxNode
{
public ITypeSymbol GetActualProxyTypeSymbol(SubstituteContext<TInvocationExpressionSyntax> substituteContext)
{
Expand Down Expand Up @@ -35,26 +34,33 @@ public ImmutableArray<ITypeSymbol> GetProxySymbols(SemanticModel semanticModel,
return methodSymbol.TypeArguments;
}

var arrayParameters = GetArrayInitializerArguments(invocationExpressionSyntax)?.ToList();
var operation = (IInvocationOperation)semanticModel.GetOperation(invocationExpressionSyntax);

if (arrayParameters == null)
{
return ImmutableArray<ITypeSymbol>.Empty;
}
var argument = operation.Arguments.First();
var typeSymbols = ArgType(argument);

var proxyTypes = GetTypeOfLikeExpressions(arrayParameters)
.Select(exp =>
semanticModel
.GetTypeInfo(exp.DescendantNodes().First()))
.Where(model => model.Type != null)
.Select(model => model.Type)
.ToImmutableArray();
return typeSymbols;
}

return arrayParameters.Count == proxyTypes.Length ? proxyTypes : ImmutableArray<ITypeSymbol>.Empty;
// TODO remove copy pasting
private ImmutableArray<ITypeSymbol> TypeSymbols(IArrayCreationOperation arrayInitializerOperation)
{
return arrayInitializerOperation.Initializer.ElementValues.OfType<ITypeOfOperation>()
.Select(op => op.TypeOperand)
.ToImmutableArray();
}

protected abstract IEnumerable<TExpressionSyntax> GetTypeOfLikeExpressions(IList<TExpressionSyntax> arrayParameters);
private ImmutableArray<ITypeSymbol> ArgType(IArgumentOperation x)
{
if (x.Value is IArrayCreationOperation arrayInitializerOperation)
{
var typeSymbols = TypeSymbols(arrayInitializerOperation);
return arrayInitializerOperation.Initializer.ElementValues.Length == typeSymbols.Length
? typeSymbols
: ImmutableArray<ITypeSymbol>.Empty;
}

protected abstract IEnumerable<TExpressionSyntax> GetArrayInitializerArguments(TInvocationExpressionSyntax invocationExpressionSyntax);
return ImmutableArray<ITypeSymbol>.Empty;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace NSubstitute.Analyzers.Shared.DiagnosticAnalyzers
{
internal interface ISubstituteProxyAnalysis<TInvocationExpressionSyntax, TExpressionSyntax> where TInvocationExpressionSyntax : SyntaxNode where TExpressionSyntax : SyntaxNode
internal interface ISubstituteProxyAnalysis<TInvocationExpressionSyntax> where TInvocationExpressionSyntax : SyntaxNode
{
ITypeSymbol GetActualProxyTypeSymbol(SubstituteContext<TInvocationExpressionSyntax> substituteContext);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace NSubstitute.Analyzers.VisualBasic.CodeFixProviders
{
[ExportCodeFixProvider(LanguageNames.VisualBasic)]
internal sealed class SubstituteForInternalMemberCodeFixProvider : AbstractSubstituteForInternalMemberCodeFixProvider<InvocationExpressionSyntax, ExpressionSyntax, CompilationUnitSyntax>
internal sealed class SubstituteForInternalMemberCodeFixProvider : AbstractSubstituteForInternalMemberCodeFixProvider<InvocationExpressionSyntax, CompilationUnitSyntax>
{
public SubstituteForInternalMemberCodeFixProvider()
: base(SubstituteProxyAnalysis.Instance)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,14 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.VisualBasic.Syntax;
using Microsoft.CodeAnalysis.VisualBasic.Syntax;
using NSubstitute.Analyzers.Shared.DiagnosticAnalyzers;
using NSubstitute.Analyzers.VisualBasic.Extensions;

namespace NSubstitute.Analyzers.VisualBasic.DiagnosticAnalyzers
{
internal sealed class SubstituteProxyAnalysis : AbstractSubstituteProxyAnalysis<InvocationExpressionSyntax, ExpressionSyntax>
internal sealed class SubstituteProxyAnalysis : AbstractSubstituteProxyAnalysis<InvocationExpressionSyntax>
{
public static SubstituteProxyAnalysis Instance { get; } = new SubstituteProxyAnalysis();

private SubstituteProxyAnalysis()
{
}

protected override IEnumerable<ExpressionSyntax> GetTypeOfLikeExpressions(IList<ExpressionSyntax> arrayParameters)
{
return arrayParameters.OfType<GetTypeExpressionSyntax>();
}

protected override IEnumerable<ExpressionSyntax> GetArrayInitializerArguments(InvocationExpressionSyntax invocationExpressionSyntax)
{
return invocationExpressionSyntax.ArgumentList?.Arguments.FirstOrDefault().GetExpression()
.GetParameterExpressionsFromArrayArgument();
}
}
}

0 comments on commit bd23284

Please sign in to comment.