Skip to content

Commit

Permalink
[GH-61] - better checks for ordinar method call
Browse files Browse the repository at this point in the history
  • Loading branch information
tpodolak committed Feb 7, 2019
1 parent 172d4ae commit 284c5f8
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using NSubstitute.Analyzers.CSharp.Extensions;
using NSubstitute.Analyzers.Shared.DiagnosticAnalyzers;

namespace NSubstitute.Analyzers.CSharp.DiagnosticAnalyzers
Expand Down Expand Up @@ -40,33 +42,21 @@ protected override SyntaxNode GetSubstituteCall(SyntaxNodeAnalysisContext syntax
}
}

// TODO fix
using (var descendantNodesEnumerator = invocationExpressionSyntax.DescendantNodes().GetEnumerator())
{
var hierarchyEnumerator = callHierarchy.GetEnumerator();
while (hierarchyEnumerator.MoveNext() && descendantNodesEnumerator.MoveNext())
{
if (descendantNodesEnumerator.Current.GetType().GetTypeInfo().IsAssignableFrom(hierarchyEnumerator.Current.GetTypeInfo()) == false)
{
return null;
}
}
var parentInvocation = invocationExpressionSyntax.GetParentInvocationExpression();

if (hierarchyEnumerator.MoveNext() == false)
{
var symbol = syntaxNodeContext.SemanticModel.GetSymbolInfo(descendantNodesEnumerator.Current);
if (parentInvocation == null)
{
return null;
}

if (symbol.Symbol is IMethodSymbol mSymbol && mSymbol.ReducedFrom == null)
{
return ((InvocationExpressionSyntax)descendantNodesEnumerator.Current).ArgumentList.Arguments
.First().Expression;
}
var symbol = syntaxNodeContext.SemanticModel.GetSymbolInfo(parentInvocation);

return descendantNodesEnumerator.Current;
}
if (symbol.Symbol is IMethodSymbol mSymbol && mSymbol.ReducedFrom == null)
{
return parentInvocation.ArgumentList.Arguments.First().Expression;
}

return null;
return parentInvocation.Expression.DescendantNodes().First();
}

protected override IEnumerable<ExpressionSyntax> GetArgumentExpressions(InvocationExpressionSyntax invocationExpressionSyntax)
Expand Down
21 changes: 21 additions & 0 deletions src/NSubstitute.Analyzers.CSharp/Extensions/SyntaxExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NSubstitute.Analyzers.Shared.Extensions;

namespace NSubstitute.Analyzers.CSharp.Extensions
{
internal static class SyntaxExtensions
{
private static readonly int[] ParentInvocationKindHierarchy =
{
(int)SyntaxKind.SimpleMemberAccessExpression,
(int)SyntaxKind.InvocationExpression
};

public static InvocationExpressionSyntax GetParentInvocationExpression(this SyntaxNode node)
{
return node.GetParentNode(ParentInvocationKindHierarchy) as InvocationExpressionSyntax;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Collections.Generic;
using Microsoft.CodeAnalysis;

namespace NSubstitute.Analyzers.Shared.Extensions
{
internal static class SyntaxNodeExtensions
{
public static SyntaxNode GetParentNode(this SyntaxNode syntaxNode, IEnumerable<int> parentNodeHierarchyKinds)
{
using (var descendantNodesEnumerator = syntaxNode.DescendantNodes().GetEnumerator())
{
using (var hierarchyKindEnumerator = parentNodeHierarchyKinds.GetEnumerator())
{
while (hierarchyKindEnumerator.MoveNext() && descendantNodesEnumerator.MoveNext())
{
if (descendantNodesEnumerator.Current.RawKind != hierarchyKindEnumerator.Current)
{
return null;
}
}

if (hierarchyKindEnumerator.MoveNext() == false)
{
return descendantNodesEnumerator.Current;
}
}
}

return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.CodeAnalysis.VisualBasic;
using Microsoft.CodeAnalysis.VisualBasic.Syntax;
using NSubstitute.Analyzers.Shared.DiagnosticAnalyzers;
using NSubstitute.Analyzers.VisualBasic.Extensions;

namespace NSubstitute.Analyzers.VisualBasic.DiagnosticAnalyzers
{
Expand Down Expand Up @@ -41,25 +42,21 @@ protected override SyntaxNode GetSubstituteCall(SyntaxNodeAnalysisContext syntax
}
}

// TODO fix
using (var descendantNodesEnumerator = invocationExpressionSyntax.DescendantNodes().GetEnumerator())
var parentInvocation = invocationExpressionSyntax.GetParentInvocationExpression();

if (parentInvocation == null)
{
var hierarchyEnumerator = callHierarchy.GetEnumerator();
while (hierarchyEnumerator.MoveNext() && descendantNodesEnumerator.MoveNext())
{
if (descendantNodesEnumerator.Current.GetType().GetTypeInfo().IsAssignableFrom(hierarchyEnumerator.Current.GetTypeInfo()) == false)
{
return null;
}
}
return null;
}

if (hierarchyEnumerator.MoveNext() == false && descendantNodesEnumerator.MoveNext())
{
return descendantNodesEnumerator.Current;
}
var symbol = syntaxNodeContext.SemanticModel.GetSymbolInfo(parentInvocation);

if (symbol.Symbol is IMethodSymbol mSymbol && mSymbol.ReducedFrom == null)
{
return parentInvocation.ArgumentList.Arguments.First().GetExpression();
}

return null;
return parentInvocation.Expression.DescendantNodes().First();
}

protected override IEnumerable<ExpressionSyntax> GetArgumentExpressions(InvocationExpressionSyntax invocationExpressionSyntax)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.VisualBasic;
using Microsoft.CodeAnalysis.VisualBasic.Syntax;
using NSubstitute.Analyzers.Shared.Extensions;

namespace NSubstitute.Analyzers.VisualBasic.Extensions
{
internal static class SyntaxExtensions
{
private static readonly int[] ParentInvocationKindHierarchy =
{
(int)SyntaxKind.SimpleMemberAccessExpression,
(int)SyntaxKind.InvocationExpression
};

public static InvocationExpressionSyntax GetParentInvocationExpression(this SyntaxNode node)
{
return node.GetParentNode(ParentInvocationKindHierarchy) as InvocationExpressionSyntax;
}
}
}

0 comments on commit 284c5f8

Please sign in to comment.