Skip to content

Commit

Permalink
Use injection
Browse files Browse the repository at this point in the history
  • Loading branch information
lconstan committed Feb 14, 2019
1 parent 6ed4196 commit d6b9037
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 105 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using JetBrains.ReSharper.Feature.Services.Daemon;
using JetBrains.DocumentModel;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Feature.Services.Daemon;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.CSharp.Tree;
using JetBrains.ReSharper.Psi.Tree;
using MoqComplete.Extensions;
using MoqComplete.Services;
using System.Linq;
using JetBrains.DocumentModel;

namespace MoqComplete.CodeAnalysis
{
Expand All @@ -13,7 +14,10 @@ public class SupiciousCallbackAnalyzer : ElementProblemAnalyzer<IInvocationExpre
{
protected override void Run(IInvocationExpression element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
{
if (!element.IsMoqCallbackMethod())
var methodIdentitifer = element.GetSolution().GetComponent<IMoqMethodIdentifier>();
var mockedMethodProvider = element.GetSolution().GetComponent<IMockedMethodProvider>();

if (!methodIdentitifer.IsMoqCallbackMethod(element))
return;

var typeParameters = element.TypeArguments;
Expand All @@ -25,7 +29,7 @@ protected override void Run(IInvocationExpression element, ElementProblemAnalyze

while (pointer != null && mockedMethod == null && pointer.FirstChild is IInvocationExpression methodInvocation)
{
mockedMethod = methodInvocation.GetMockedMethodFromSetupMethod();
mockedMethod = mockedMethodProvider.GetMockedMethodFromSetupMethod(methodInvocation);
pointer = methodInvocation.InvokedExpression;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using JetBrains.ReSharper.Feature.Services.CodeCompletion;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Feature.Services.CodeCompletion;
using JetBrains.ReSharper.Feature.Services.CodeCompletion.Infrastructure;
using JetBrains.ReSharper.Feature.Services.CodeCompletion.Infrastructure.AspectLookupItems.BaseInfrastructure;
using JetBrains.ReSharper.Feature.Services.CodeCompletion.Infrastructure.AspectLookupItems.Info;
Expand All @@ -12,6 +13,7 @@
using JetBrains.ReSharper.Psi.Resources;
using JetBrains.ReSharper.Psi.Tree;
using MoqComplete.Extensions;
using MoqComplete.Services;
using System.Linq;

namespace MoqComplete.CompletionProvider
Expand All @@ -27,6 +29,8 @@ protected override bool IsAvailable(CSharpCodeCompletionContext context)

protected override bool AddLookupItems(CSharpCodeCompletionContext context, IItemsCollector collector)
{
var methodIdentitifer = context.BasicContext.Solution.GetComponent<IMoqMethodIdentifier>();
var mockedMethodProvider = context.BasicContext.Solution.GetComponent<IMockedMethodProvider>();
var identifier = context.TerminatedContext.TreeNode as IIdentifier;
var expression = identifier.GetParentSafe<IReferenceExpression>();
if (expression == null)
Expand All @@ -35,10 +39,10 @@ protected override bool AddLookupItems(CSharpCodeCompletionContext context, IIte
if (!(expression.ConditionalQualifier is IInvocationExpression invocation))
return false;

if (invocation.IsMoqReturnMethod())
if (methodIdentitifer.IsMoqReturnMethod(invocation))
invocation = invocation.InvokedExpression?.FirstChild as IInvocationExpression;
var mockedMethod = invocation.GetMockedMethodFromSetupMethod();

var mockedMethod = mockedMethodProvider.GetMockedMethodFromSetupMethod(invocation);

if (mockedMethod == null || mockedMethod.Parameters.Count == 0)
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using JetBrains.ReSharper.Feature.Services.CodeCompletion;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Feature.Services.CodeCompletion;
using JetBrains.ReSharper.Feature.Services.CodeCompletion.Infrastructure;
using JetBrains.ReSharper.Feature.Services.CodeCompletion.Infrastructure.LookupItems;
using JetBrains.ReSharper.Feature.Services.CSharp.CodeCompletion.Infrastructure;
Expand All @@ -10,8 +11,8 @@
using JetBrains.ReSharper.Psi.Resources;
using JetBrains.ReSharper.Psi.Tree;
using MoqComplete.Extensions;
using MoqComplete.Services;
using System.Linq;
using JetBrains.DocumentModel;

namespace MoqComplete.CompletionProvider
{
Expand All @@ -26,6 +27,7 @@ protected override bool IsAvailable(CSharpCodeCompletionContext context)

protected override bool AddLookupItems(CSharpCodeCompletionContext context, IItemsCollector collector)
{
var methodIdentitifer = context.BasicContext.Solution.GetComponent<IMoqMethodIdentifier>();
var identifier = context.TerminatedContext.TreeNode as IIdentifier;
var mockedMethodArgument = identifier.GetParentSafe<IReferenceExpression>().GetParentSafe<ICSharpArgument>();

Expand All @@ -45,8 +47,8 @@ protected override bool AddLookupItems(CSharpCodeCompletionContext context, IIte
if (methodInvocation == null)
return false;

var isSetup = methodInvocation.IsMoqSetupMethod();
var isVerify = methodInvocation.IsMoqVerifyMethod();
var isSetup = methodIdentitifer.IsMoqSetupMethod(methodInvocation);
var isVerify = methodIdentitifer.IsMoqVerifyMethod(methodInvocation);

if (!isSetup && !isVerify)
return false;
Expand Down
91 changes: 0 additions & 91 deletions Abc.MoqComplete/MoqComplete/Extensions/MoqExtensions.cs

This file was deleted.

5 changes: 4 additions & 1 deletion Abc.MoqComplete/MoqComplete/MoqComplete.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,12 @@
<Compile Include="CompletionProvider\CallbackMethodProvider.cs" />
<Compile Include="CompletionProvider\ItIsAnyParameterProvider.cs" />
<Compile Include="CompletionProvider\SuggestMockProvider.cs" />
<Compile Include="Extensions\MoqExtensions.cs" />
<Compile Include="Extensions\ResharperExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\IMockedMethodProvider.cs" />
<Compile Include="Services\IMoqMethodIdentifier.cs" />
<Compile Include="Services\MockedMethodProvider.cs" />
<Compile Include="Services\MoqMethodIdentifier.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Antlr2.Tools">
Expand Down
11 changes: 11 additions & 0 deletions Abc.MoqComplete/MoqComplete/Services/IMockedMethodProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using JetBrains.Annotations;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.CSharp.Tree;

namespace MoqComplete.Services
{
public interface IMockedMethodProvider
{
IMethod GetMockedMethodFromSetupMethod([CanBeNull] IInvocationExpression invocationExpression);
}
}
13 changes: 13 additions & 0 deletions Abc.MoqComplete/MoqComplete/Services/IMoqMethodIdentifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using JetBrains.Annotations;
using JetBrains.ReSharper.Psi.CSharp.Tree;

namespace MoqComplete.Services
{
public interface IMoqMethodIdentifier
{
bool IsMoqSetupMethod([CanBeNull] IInvocationExpression invocationExpression);
bool IsMoqVerifyMethod([CanBeNull] IInvocationExpression invocationExpression);
bool IsMoqReturnMethod([CanBeNull] IInvocationExpression invocationExpression);
bool IsMoqCallbackMethod([CanBeNull] IInvocationExpression invocationExpression);
}
}
44 changes: 44 additions & 0 deletions Abc.MoqComplete/MoqComplete/Services/MockedMethodProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.CSharp.Tree;
using JetBrains.ReSharper.Psi.Resolve;

namespace MoqComplete.Services
{
[SolutionComponent]
public class MockedMethodProvider : IMockedMethodProvider
{
private readonly IMoqMethodIdentifier _methodIdentifier;

public MockedMethodProvider(IMoqMethodIdentifier methodIdentifier)
{
_methodIdentifier = methodIdentifier;
}

public IMethod GetMockedMethodFromSetupMethod(IInvocationExpression invocationExpression)
{
if (invocationExpression == null || !_methodIdentifier.IsMoqSetupMethod(invocationExpression))
return null;

var methodArguments = invocationExpression.ArgumentList.Arguments;
if (methodArguments.Count != 1)
return null;

var lambdaExpression = methodArguments[0].Value as ILambdaExpression;
if (lambdaExpression == null)
return null;

var mockMethodInvocationExpression = lambdaExpression.BodyExpression as IInvocationExpression;
if (mockMethodInvocationExpression == null || mockMethodInvocationExpression.Reference == null)
return null;

var targetMethodResolveResult = mockMethodInvocationExpression.Reference.Resolve();
if (targetMethodResolveResult.ResolveErrorType == ResolveErrorType.OK)
{
return targetMethodResolveResult.DeclaredElement as IMethod;
}

return null;
}
}
}
63 changes: 63 additions & 0 deletions Abc.MoqComplete/MoqComplete/Services/MoqMethodIdentifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using JetBrains.Annotations;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.CSharp.Tree;
using JetBrains.ReSharper.Psi.Resolve;
using JetBrains.ReSharper.Psi.Resx.Utils;
using System;
using System.Linq;

namespace MoqComplete.Services
{
[SolutionComponent]
public class MoqMethodIdentifier : IMoqMethodIdentifier
{
public bool IsMoqSetupMethod(IInvocationExpression invocationExpression)
=> IsMethod(invocationExpression,
declaredElement => IsMethodString(declaredElement,
"Method:Moq.Mock`1.Setup(System.Linq.Expressions.Expression`1[TDelegate -> System.Action`1[T -> T]] expression)",
"Method:Moq.Mock`1.Setup(System.Linq.Expressions.Expression`1[TDelegate -> System.Func`2[T -> T, TResult -> TResult]] expression)"));

public bool IsMoqVerifyMethod(IInvocationExpression invocationExpression)
=> IsMethod(invocationExpression,
declaredElement => IsMethodString(declaredElement,
"Method:Moq.Mock`1.Verify(System.Linq.Expressions.Expression`1[TDelegate -> System.Action`1[T -> T]] expression)",
"Method:Moq.Mock`1.Verify(System.Linq.Expressions.Expression`1[TDelegate -> System.Func`2[T -> T, TResult -> TResult]] expression)"));

public bool IsMoqReturnMethod(IInvocationExpression invocationExpression)
=> IsMethod(invocationExpression,
declaredElement => IsMethodStartingWithString(declaredElement,
"Method:Moq.Language.IReturns`2.Returns",
"Method:Moq.Language.IReturns`1.Returns"));

public bool IsMoqCallbackMethod(IInvocationExpression expression)
=> IsMethod(expression,
declaredElement => IsMethodStartingWithString(declaredElement,
"Method:Moq.Language.ICallback.Callback(System.Action",
"Method:Moq.Language.ICallback`2.Callback(System.Action"));

private bool IsMethod([CanBeNull] IInvocationExpression invocationExpression, Func<IDeclaredElement, bool> methodFilter)
{
if (invocationExpression == null || invocationExpression.Reference == null)
return false;

var resolveResult = invocationExpression.Reference.Resolve();
if (resolveResult.ResolveErrorType == ResolveErrorType.MULTIPLE_CANDIDATES)
return resolveResult.Result.Candidates.Any(methodFilter);

return methodFilter(resolveResult.DeclaredElement);
}

private bool IsMethodString([CanBeNull] IDeclaredElement declaredElement, params string[] methodName)
{
var declaredElementAsString = declaredElement.ConvertToString();
return methodName.Contains(declaredElementAsString);
}

private bool IsMethodStartingWithString([CanBeNull] IDeclaredElement declaredElement, params string[] methodName)
{
var methodString = declaredElement.ConvertToString();
return methodString != null && methodName.Any(m => methodString.StartsWith(m));
}
}
}

0 comments on commit d6b9037

Please sign in to comment.