Skip to content

Commit

Permalink
GH-108 - finding non-virtual calls within Received.InOrder block
Browse files Browse the repository at this point in the history
  • Loading branch information
tpodolak committed Aug 9, 2020
1 parent b87e925 commit b890a86
Show file tree
Hide file tree
Showing 511 changed files with 1,664 additions and 30 deletions.
Empty file modified .gitattributes
100644 → 100755
Empty file.
Empty file modified .gitignore
100644 → 100755
Empty file.
Empty file modified Acknowledgements.md
100644 → 100755
Empty file.
Empty file modified Analyzers.ruleset
100644 → 100755
Empty file.
Empty file modified Directory.Build.props
100644 → 100755
Empty file.
Empty file modified LICENSE.md
100644 → 100755
Empty file.
Empty file modified NSubstitute.Analyzers.All.sln
100644 → 100755
Empty file.
3 changes: 2 additions & 1 deletion NSubstitute.Analyzers.sln
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ ProjectSection(SolutionItems) = preProject
documentation\rules\NS1001.md = documentation\rules\NS1001.md
documentation\rules\NS1002.md = documentation\rules\NS1002.md
documentation\rules\NS1003.md = documentation\rules\NS1003.md
documentation\rules\NS1003.md = documentation\rules\NS1004.md
documentation\rules\NS1004.md = documentation\rules\NS1004.md
documentation\rules\NS1005.md = documentation\rules\NS1005.md
documentation\rules\NS2000.md = documentation\rules\NS2000.md
documentation\rules\NS2001.md = documentation\rules\NS2001.md
documentation\rules\NS2002.md = documentation\rules\NS2002.md
Expand Down
Empty file modified README.md
100644 → 100755
Empty file.
Empty file modified ReleaseNotes.md
100644 → 100755
Empty file.
Empty file modified StyleCop.json
100644 → 100755
Empty file.
Empty file modified appveyor.yml
100644 → 100755
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using NSubstitute.Analyzers.Benchmarks.Source.CSharp.Models;

namespace NSubstitute.Analyzers.Benchmarks.Source.CSharp.DiagnosticsSources
{
public class NonSubstitutableMemberReceivedInOrderDiagnosticSource
{
public void NS1005_NonVirtualSetupSpecification()
{
var substitute = Substitute.For<Foo>();

Received.InOrder(() =>
{
substitute.ObjectReturningMethod();
var methodItem = substitute.ObjectReturningMethod();
substitute.ObjectReturningMethodWithArguments(substitute.IntReturningProperty, 1, 1m);
_ = substitute.IntReturningProperty;
var propertyItem = substitute.IntReturningProperty;
_ = substitute[0];
var indexerItem = substitute[0];
var otherIndexerItem = substitute[0];
var usedIndexerItem = otherIndexerItem;
});
}

public void NS1003_InternalVirtualSetupSpecification()
{
var substitute = Substitute.For<Foo>();

substitute.InternalObjectReturningMethod();
var methodItem = substitute.InternalObjectReturningMethod();
substitute.InternalObjectReturningMethodWithArguments(substitute.IntReturningProperty);
_ = substitute.InternalObjectReturningProperty;
var propertyItem = substitute.InternalObjectReturningProperty;
_ = substitute[0];
var indexerItem = substitute[0, 0, 0];
var otherIndexerItem = substitute[0, 0, 0];
var usedIndexerItem = otherIndexerItem;
}
}
}
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public class CSharpDiagnosticAnalyzersBenchmarks : AbstractDiagnosticAnalyzersBe

protected override AnalyzerBenchmark NonSubstitutableMemberWhenAnalyzerBenchmark { get; }

protected override AnalyzerBenchmark NonSubstitutableMemberReceivedInOrderAnalyzerBenchmark { get; }

protected override AnalyzerBenchmark ReEntrantSetupAnalyzerBenchmark { get; }

protected override AnalyzerBenchmark SubstituteAnalyzerBenchmark { get; }
Expand Down Expand Up @@ -46,6 +48,7 @@ public CSharpDiagnosticAnalyzersBenchmarks()
NonSubstitutableMemberAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new NonSubstitutableMemberAnalyzer());
NonSubstitutableMemberReceivedAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new NonSubstitutableMemberReceivedAnalyzer());
NonSubstitutableMemberWhenAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new NonSubstitutableMemberWhenAnalyzer());
NonSubstitutableMemberReceivedInOrderAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new NonSubstitutableMemberReceivedInOrderAnalyzer());
ReEntrantSetupAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new ReEntrantSetupAnalyzer());
SubstituteAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new SubstituteAnalyzer());
UnusedReceivedAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new UnusedReceivedAnalyzer());
Expand Down
Empty file.
Empty file.
Empty file modified benchmarks/NSubstitute.Analyzers.Benchmarks/Program.cs
100644 → 100755
Empty file.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public abstract class AbstractDiagnosticAnalyzersBenchmarks

protected abstract AnalyzerBenchmark NonSubstitutableMemberWhenAnalyzerBenchmark { get; }

protected abstract AnalyzerBenchmark NonSubstitutableMemberReceivedInOrderAnalyzerBenchmark { get; }

protected abstract AnalyzerBenchmark ReEntrantSetupAnalyzerBenchmark { get; }

protected abstract AnalyzerBenchmark SubstituteAnalyzerBenchmark { get; }
Expand Down Expand Up @@ -79,6 +81,12 @@ public void NonSubstitutableMemberWhenAnalyzer()
NonSubstitutableMemberWhenAnalyzerBenchmark.Run();
}

[Benchmark]
public void NonSubstitutableMemberReceivedInOrderAnalyzer()
{
NonSubstitutableMemberReceivedInOrderAnalyzerBenchmark.Run();
}

[Benchmark]
public void ReEntrantSetupAnalyzer()
{
Expand Down
Empty file.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public class VisualBasicDiagnosticAnalyzersBenchmarks : AbstractDiagnosticAnalyz

protected override AnalyzerBenchmark NonSubstitutableMemberWhenAnalyzerBenchmark { get; }

protected override AnalyzerBenchmark NonSubstitutableMemberReceivedInOrderAnalyzerBenchmark { get; }

protected override AnalyzerBenchmark ReEntrantSetupAnalyzerBenchmark { get; }

protected override AnalyzerBenchmark SubstituteAnalyzerBenchmark { get; }
Expand Down Expand Up @@ -46,6 +48,7 @@ public VisualBasicDiagnosticAnalyzersBenchmarks()
NonSubstitutableMemberAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new NonSubstitutableMemberAnalyzer());
NonSubstitutableMemberReceivedAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new NonSubstitutableMemberReceivedAnalyzer());
NonSubstitutableMemberWhenAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new NonSubstitutableMemberWhenAnalyzer());
NonSubstitutableMemberReceivedInOrderAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new NonSubstitutableMemberReceivedInOrderAnalyzer());
ReEntrantSetupAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new ReEntrantSetupAnalyzer());
SubstituteAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new SubstituteAnalyzer());
UnusedReceivedAnalyzerBenchmark = AnalyzerBenchmark.CreateBenchmark(Solution, new UnusedReceivedAnalyzer());
Expand Down
Empty file.
Empty file modified build/build.cake
100644 → 100755
Empty file.
Empty file modified build/build.config
100644 → 100755
Empty file.
Empty file modified build/build.ps1
100644 → 100755
Empty file.
Empty file modified build/build.sh
100644 → 100755
Empty file.
Empty file modified build/parameters.cake
100644 → 100755
Empty file.
Empty file modified build/paths.cake
100644 → 100755
Empty file.
Empty file modified build/releasenotes.cake
100644 → 100755
Empty file.
Empty file modified build/table-of-contents.cake
100644 → 100755
Empty file.
Empty file modified build/version.cake
100644 → 100755
Empty file.
Empty file modified documentation/Compatibility.md
100644 → 100755
Empty file.
Empty file modified documentation/Configuration.md
100644 → 100755
Empty file.
Empty file modified documentation/README.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS1000.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS1001.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS1002.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS1003.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS1004.md
100644 → 100755
Empty file.
39 changes: 39 additions & 0 deletions documentation/rules/NS1005.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# NS1005

<table>
<tr>
<td>CheckId</td>
<td>NS1005</td>
</tr>
<tr>
<td>Category</td>
<td>Non-substitutable member</td>
</tr>
</table>

## Cause

Checking call order for non-virtual member of a class.

## Rule description

A violation of this rule occurs when `Received.InOrder` checks call order for non-virtual member of a class.

## How to fix violations

To fix a violation of this rule, make the member of your class virtual or substitute for interface.

## How to suppress violations

This warning can be suppressed by disabling the warning in the **ruleset** file for the project or by suppressing it (for selected members) in `nsubstitute.json` file. See the [configuration](../Configuration.md) section for details on how to set this up.
The warning can also be suppressed programmatically for an assembly:
````c#
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Non-substitutable member", "NS1005:Non-virtual setup specification.", Justification = "Reviewed")]
````

Or for a specific code block:
````c#
#pragma warning disable NS1005 // Non-virtual setup specification.
// the code which produces warning
#pragma warning restore NS1005 // Non-virtual setup specification.
````
Empty file modified documentation/rules/NS2000.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS2001.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS2002.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS2003.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS2004.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS2005.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS2006.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS2007.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS3000.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS3001.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS3002.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS3003.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS3004.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS3005.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS3006.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS4000.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS5000.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS5001.md
100644 → 100755
Empty file.
Empty file modified documentation/rules/NS5002.md
100644 → 100755
Empty file.
3 changes: 2 additions & 1 deletion documentation/rules/README.md
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
| [NS1002](NS1002.md) | Non-substitutable member | Substituting for non-virtual member of a class. |
| [NS1003](NS1003.md) | Non-substitutable member | Substituting for an internal member of a class without proxies having visibility into internal members. |
| [NS1004](NS1004.md) | Non-substitutable member | Argument matcher used with a non-virtual member of a class. |
| [NS1005](NS1005.md) | Non-substitutable member | Checking call order for non-virtual member of a class. |
| [NS2000](NS2000.md) | Substitute creation | Substitute.ForPartsOf used with interface or delegate. |
| [NS2001](NS2001.md) | Substitute creation | NSubstitute used with class which does not expose public or protected constructor. |
| [NS2002](NS2002.md) | Substitute creation | NSubstitute used with class which does not expose parameterless constructor. |
Expand All @@ -26,4 +27,4 @@
| [NS4000](NS4000.md) | Call configuration | Calling substitute from within `Returns` block. |
| [NS5000](NS5000.md) | Usage | Checking received calls without specifying member. |
| [NS5001](NS5001.md) | Usage | Usage of received-like method in `Received.InOrder` callback. |
| [NS5002](NS5002.md) | Usage | Usage of async callback in `Received.InOrder` method. |
| [NS5002](NS5002.md) | Usage | Usage of async callback in `Received.InOrder` method. |
Empty file modified global.json
100644 → 100755
Empty file.
Empty file modified images/csharp-example.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified images/nsubstitute-analyser.ai
100644 → 100755
Empty file.
Empty file modified images/nsubstitute-analyser.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified images/nsubstitute-analyser@0,25x.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified images/nsubstitute-analyser@0,5x.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified images/nsubstitute-analyser@1x.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified images/vb-example.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified nsubstitute.snk
100644 → 100755
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace NSubstitute.Analyzers.CSharp.DiagnosticAnalyzers
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
internal class NonSubstitutableMemberReceivedInOrderAnalyzer : AbstractNonSubstitutableMemberReceivedInOrderAnalyzer<SyntaxKind, InvocationExpressionSyntax, MemberAccessExpressionSyntax>
internal sealed class NonSubstitutableMemberReceivedInOrderAnalyzer : AbstractNonSubstitutableMemberReceivedInOrderAnalyzer<SyntaxKind, InvocationExpressionSyntax, MemberAccessExpressionSyntax, BlockSyntax>
{
private static ImmutableArray<ImmutableArray<int>> IgnoredPaths { get; } = ImmutableArray.Create(
ImmutableArray.Create(
Expand All @@ -17,14 +17,6 @@ internal class NonSubstitutableMemberReceivedInOrderAnalyzer : AbstractNonSubsti
(int)SyntaxKind.CastExpression,
(int)SyntaxKind.Argument),
ImmutableArray.Create(
(int)SyntaxKind.EqualsValueClause,
(int)SyntaxKind.VariableDeclarator),
ImmutableArray.Create(
(int)SyntaxKind.CastExpression,
(int)SyntaxKind.EqualsValueClause,
(int)SyntaxKind.VariableDeclarator),
ImmutableArray.Create(
(int)SyntaxKind.AsExpression,
(int)SyntaxKind.EqualsValueClause,
(int)SyntaxKind.VariableDeclarator));

Expand All @@ -36,5 +28,10 @@ public NonSubstitutableMemberReceivedInOrderAnalyzer()
protected override SyntaxKind InvocationExpressionKind { get; } = SyntaxKind.InvocationExpression;

protected override ImmutableArray<ImmutableArray<int>> IgnoredAncestorPaths { get; } = IgnoredPaths;

protected override ISymbol GetDeclarationSymbol(SemanticModel semanticModel, SyntaxNode node)
{
return semanticModel.GetDeclaredSymbol(node);
}
}
}
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file modified src/NSubstitute.Analyzers.CSharp/Extensions/SyntaxExtensions.cs
100644 → 100755
Empty file.
Empty file.
Empty file modified src/NSubstitute.Analyzers.CSharp/Properties/AssemblyInfo.cs
100644 → 100755
Empty file.
Empty file.
Empty file.
Empty file.
4 changes: 2 additions & 2 deletions src/NSubstitute.Analyzers.CSharp/Resources.Designer.cs
100644 → 100755

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/NSubstitute.Analyzers.CSharp/Resources.resx
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
<value>Member {0} can not be intercepted. Only interface members and virtual, overriding, and abstract members can be intercepted.</value>
<comment>The format-able message the diagnostic displays.</comment>
</data>
<data name="NonVirtualReceivedInOrderSetupSpecificationTitleMessageFormat" xml:space="preserve">
<data name="NonVirtualReceivedInOrderSetupSpecificationMessageFormat" xml:space="preserve">
<value>Member {0} can not be intercepted. Only interface members and virtual, overriding, and abstract members can be intercepted.</value>
<comment>The format-able message the diagnostic displays.</comment>
</data>
Expand Down
Empty file modified src/NSubstitute.Analyzers.CSharp/tools/install.ps1
100644 → 100755
Empty file.
Empty file modified src/NSubstitute.Analyzers.CSharp/tools/uninstall.ps1
100644 → 100755
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ namespace NSubstitute.Analyzers.Shared.CodeFixProviders
{
internal class AbstractNonSubstitutableMemberSuppressDiagnosticsCodeFixProvider : AbstractSuppressDiagnosticsCodeFixProvider
{
public override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(DiagnosticIdentifiers.NonVirtualSetupSpecification);
public override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(
DiagnosticIdentifiers.NonVirtualSetupSpecification,
DiagnosticIdentifiers.NonVirtualReceivedInOrderSetupSpecification);
}
}
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ protected override void InitializeAnalyzer(AnalysisContext context)
return false;
}

return symbolInfo.Symbol?.CanBeSetuped();
return symbolInfo.Symbol?.CanBeSubstituted();
}

private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ private void AnalyzeArgLikeMethod(SyntaxNodeAnalysisContext syntaxNodeContext, T
return;
}

var canBeSetuped = enclosingExpressionSymbol.CanBeSetuped();
var canBeSetuped = enclosingExpressionSymbol.CanBeSubstituted();

if (canBeSetuped == false || enclosingExpressionSymbol.MemberVisibleToProxyGenerator() == false)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext)
return;
}

var canBeSetuped = symbolInfo.Symbol.CanBeSetuped();
var canBeSetuped = symbolInfo.Symbol.CanBeSubstituted();

if (canBeSetuped == false)
{
Expand Down
38 changes: 34 additions & 4 deletions ...yzers.Shared/DiagnosticAnalyzers/AbstractNonSubstitutableMemberReceivedInOrderAnalyzer.cs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@

namespace NSubstitute.Analyzers.Shared.DiagnosticAnalyzers
{
internal abstract class AbstractNonSubstitutableMemberReceivedInOrderAnalyzer<TSyntaxKind, TInvocationExpressionSyntax, TMemberAccessExpressionSyntax> : AbstractDiagnosticAnalyzer
internal abstract class AbstractNonSubstitutableMemberReceivedInOrderAnalyzer<TSyntaxKind, TInvocationExpressionSyntax, TMemberAccessExpressionSyntax, TBlockStatementSyntax> : AbstractDiagnosticAnalyzer
where TSyntaxKind : struct
where TInvocationExpressionSyntax : SyntaxNode
where TMemberAccessExpressionSyntax : SyntaxNode
where TBlockStatementSyntax : SyntaxNode
{
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }

Expand Down Expand Up @@ -38,6 +39,8 @@ protected sealed override void InitializeAnalyzer(AnalysisContext context)
context.RegisterSyntaxNodeAction(_analyzeInvocationAction, InvocationExpressionKind);
}

protected abstract ISymbol GetDeclarationSymbol(SemanticModel semanticModel, SyntaxNode node);

private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext)
{
var invocationExpression = (TInvocationExpressionSyntax)syntaxNodeContext.Node;
Expand All @@ -56,7 +59,7 @@ private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext)
foreach (var syntaxNode in _substitutionNodeFinder.FindForReceivedInOrderExpression(
syntaxNodeContext,
invocationExpression,
(IMethodSymbol)methodSymbolInfo.Symbol).Where(node => FindIgnoredEnclosingExpression(node) == null))
(IMethodSymbol)methodSymbolInfo.Symbol).Where(node => ShouldAnalyzeNode(syntaxNodeContext.SemanticModel, node)))
{
var symbolInfo = syntaxNodeContext.SemanticModel.GetSymbolInfo(syntaxNode);

Expand All @@ -65,7 +68,7 @@ private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext)
return;
}

var canBeSetuped = symbolInfo.Symbol.CanBeSetuped();
var canBeSetuped = symbolInfo.Symbol.CanBeSubstituted();

if (canBeSetuped == false)
{
Expand All @@ -74,7 +77,7 @@ private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext)
GetSubstitutionNodeActualLocation(syntaxNode, symbolInfo.Symbol),
symbolInfo.Symbol.Name);

syntaxNodeContext.ReportDiagnostic(diagnostic);
TryReportDiagnostic(syntaxNodeContext, diagnostic, symbolInfo.Symbol);
}

if (canBeSetuped && symbolInfo.Symbol != null && symbolInfo.Symbol.MemberVisibleToProxyGenerator() == false)
Expand All @@ -89,6 +92,33 @@ private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext)
}
}

private bool ShouldAnalyzeNode(SemanticModel semanticModel, SyntaxNode syntaxNode)
{
var maybeIgnoredExpression = FindIgnoredEnclosingExpression(syntaxNode);
if (maybeIgnoredExpression == null)
{
return true;
}

var symbol = GetDeclarationSymbol(semanticModel, maybeIgnoredExpression);

if (symbol == null)
{
return false;
}

var blockStatementSyntax =
maybeIgnoredExpression.Ancestors().OfType<TBlockStatementSyntax>().FirstOrDefault();

if (blockStatementSyntax == null)
{
return false;
}

var dataFlowAnalysis = semanticModel.AnalyzeDataFlow(blockStatementSyntax);
return !dataFlowAnalysis.ReadInside.Contains(symbol);
}

private Location GetSubstitutionNodeActualLocation(SyntaxNode syntaxNode, ISymbol symbol)
{
return syntaxNode.GetSubstitutionNodeActualLocation<TMemberAccessExpressionSyntax>(symbol);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext)
var symbolInfo = syntaxNodeContext.SemanticModel.GetSymbolInfo(analysedSyntax);
if (symbolInfo.Symbol != null)
{
var canBeSetuped = symbolInfo.Symbol.CanBeSetuped();
var canBeSetuped = symbolInfo.Symbol.CanBeSubstituted();
if (canBeSetuped == false)
{
var diagnostic = Diagnostic.Create(
Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/DiagnosticCategories.cs
100644 → 100755
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/DiagnosticDescriptors.cs
100644 → 100755
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/DiagnosticIdentifiers.cs
100644 → 100755
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/DisplayNameAttribute.cs
100644 → 100755
Empty file.
Empty file.
Empty file.
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/Extensions/EnumExtensions.cs
100644 → 100755
Empty file.
Empty file.
Empty file.
2 changes: 1 addition & 1 deletion src/NSubstitute.Analyzers.Shared/Extensions/ISymbolExtensions.cs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace NSubstitute.Analyzers.Shared.Extensions
{
internal static class ISymbolExtensions
{
public static bool CanBeSetuped(this ISymbol symbol)
public static bool CanBeSubstituted(this ISymbol symbol)
{
return IsInterfaceMember(symbol) || IsVirtual(symbol);
}
Expand Down
Empty file modified src/NSubstitute.Analyzers.Shared/Extensions/ObjectExtensions.cs
100644 → 100755
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/GlobalSuppressions.cs
100644 → 100755
Empty file.
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/MetadataNames.cs
100644 → 100755
Empty file.
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/Properties/AssemblyInfo.cs
100644 → 100755
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/Resources.Designer.cs
100644 → 100755
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/Resources.resx
100644 → 100755
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/Settings/AnalyzersSettings.cs
100644 → 100755
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/Settings/Suppression.cs
100644 → 100755
Empty file.
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/SharedResourceManager.cs
100644 → 100755
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/TinyJson/Json.cs
100644 → 100755
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/TinyJson/JsonBuilder.cs
100644 → 100755
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/TinyJson/JsonMapper.cs
100644 → 100755
Empty file.
Empty file modified src/NSubstitute.Analyzers.Shared/TinyJson/JsonParser.cs
100644 → 100755
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Loading

0 comments on commit b890a86

Please sign in to comment.