Skip to content

Commit

Permalink
[GH-89] - Correctly reporting non-virtual member usage for When metho…
Browse files Browse the repository at this point in the history
…ds calling non-virtual member from base class
  • Loading branch information
tpodolak committed Apr 7, 2019
1 parent fe9220f commit 1f39be9
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,10 @@ private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxNodeContext)
}

var expressionsForAnalysys = _substitutionNodeFinder.FindForWhenExpression(syntaxNodeContext, invocationExpression, methodSymbol);
var typeSymbol = methodSymbol.TypeArguments.FirstOrDefault() ?? methodSymbol.ReceiverType;
foreach (var analysedSyntax in expressionsForAnalysys)
{
var symbolInfo = syntaxNodeContext.SemanticModel.GetSymbolInfo(analysedSyntax);
if (symbolInfo.Symbol != null && symbolInfo.Symbol.ContainingType == typeSymbol)
if (symbolInfo.Symbol != null)
{
var canBeSetuped = symbolInfo.Symbol.CanBeSetuped();
if (canBeSetuped == false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ public abstract class NonSubstitutableMemberWhenDiagnosticVerifier : CSharpDiagn
[InlineData("sub => { [|sub.Bar()|]; }")]
public abstract Task ReportsDiagnostics_WhenSettingValueForNonVirtualMethod(string method, string whenAction);

[CombinatoryTheory]
[InlineData("sub => [|sub.Bar()|]")]
[InlineData("delegate(Foo sub) { [|sub.Bar()|]; }")]
[InlineData("sub => { [|sub.Bar()|]; }")]
public abstract Task ReportsDiagnostics_WhenSettingValueForNonVirtualMemberFromBaseClass(string method, string whenAction);

[CombinatoryTheory]
[InlineData("sub => sub.Bar()")]
[InlineData("delegate(Foo sub) { sub.Bar(); }")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,37 @@ public void Test()
await VerifyDiagnostic(source, NonVirtualWhenSetupSpecificationDescriptor, "Member Bar can not be intercepted. Only interface members and virtual, overriding, and abstract members can be intercepted.");
}

public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualMemberFromBaseClass(string method, string whenAction)
{
var source = $@"using NSubstitute;
namespace MyNamespace
{{
public abstract class FooBar
{{
public int Bar()
{{
return 1;
}}
}}
public class Foo : FooBar
{{
}}
public class FooTests
{{
public void Test()
{{
int i = 1;
var substitute = Substitute.For<Foo>();
substitute.{method}({whenAction}).Do(callInfo => i++);
}}
}}
}}";
await VerifyDiagnostic(source, NonVirtualWhenSetupSpecificationDescriptor, "Member Bar can not be intercepted. Only interface members and virtual, overriding, and abstract members can be intercepted.");
}

public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualMethod(string method, string whenAction)
{
var source = $@"using NSubstitute;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,37 @@ public void Test()
await VerifyDiagnostic(source, NonVirtualWhenSetupSpecificationDescriptor, "Member Bar can not be intercepted. Only interface members and virtual, overriding, and abstract members can be intercepted.");
}

public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualMemberFromBaseClass(string method, string whenAction)
{
var source = $@"using NSubstitute;
namespace MyNamespace
{{
public abstract class FooBar
{{
public int Bar()
{{
return 1;
}}
}}
public class Foo : FooBar
{{
}}
public class FooTests
{{
public void Test()
{{
int i = 1;
var substitute = Substitute.For<Foo>();
{method}(substitute, {whenAction}).Do(callInfo => i++);
}}
}}
}}";
await VerifyDiagnostic(source, NonVirtualWhenSetupSpecificationDescriptor, "Member Bar can not be intercepted. Only interface members and virtual, overriding, and abstract members can be intercepted.");
}

public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualMethod(string method, string whenAction)
{
var source = $@"using NSubstitute;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ public interface INonSubstitutableMemberWhenDiagnosticVerifier
{
Task ReportsDiagnostics_WhenSettingValueForNonVirtualMethod(string method, string whenAction);

Task ReportsDiagnostics_WhenSettingValueForNonVirtualMemberFromBaseClass(string method, string whenAction);

Task ReportsNoDiagnostics_WhenSettingValueForVirtualMethod(string method, string whenAction);

Task ReportsNoDiagnostics_WhenSettingValueForNonSealedOverrideMethod(string method, string whenAction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ public abstract class NonSubstitutableMemberWhenDiagnosticVerifier : VisualBasic
End Sub")]
public abstract Task ReportsDiagnostics_WhenSettingValueForNonVirtualMethod(string method, string whenAction);

[CombinatoryTheory]
[InlineData("Sub(sb) [|sb.Bar()|]")]
[InlineData(@"Function(ByVal [sub] As Foo) [|[sub].Bar()|]")]
[InlineData(
@"Sub(sb As Foo)
[|sb.Bar()|]
End Sub")]
public abstract Task ReportsDiagnostics_WhenSettingValueForNonVirtualMemberFromBaseClass(string method, string whenAction);

[CombinatoryTheory]
[InlineData("Sub(sb) sb.Bar()")]
[InlineData(@"Function(ByVal [sub] As Foo) [sub].Bar()")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,33 @@ End Namespace
await VerifyDiagnostic(source, NonVirtualWhenSetupSpecificationDescriptor, "Member Bar can not be intercepted. Only interface members and overrideable, overriding, and must override members can be intercepted.");
}

public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualMemberFromBaseClass(string method, string whenAction)
{
var source = $@"Imports NSubstitute
Namespace MyNamespace
Public MustInherit Class FooBar
Public Function Bar() As Integer
Return 1
End Function
End Class
Public Class Foo
Inherits FooBar
End Class
Public Class FooTests
Public Sub Test()
Dim i As Integer = 1
Dim substitute = NSubstitute.Substitute.[For](Of Foo)()
substitute.{method}({whenAction}).[Do](Sub(callInfo) i = i + 1)
End Sub
End Class
End Namespace";

await VerifyDiagnostic(source, NonVirtualWhenSetupSpecificationDescriptor, "Member Bar can not be intercepted. Only interface members and overrideable, overriding, and must override members can be intercepted.");
}

public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualMethod(string method, string whenAction)
{
var source = $@"Imports NSubstitute
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,33 @@ End Namespace
await VerifyDiagnostic(source, NonVirtualWhenSetupSpecificationDescriptor, "Member Bar can not be intercepted. Only interface members and overrideable, overriding, and must override members can be intercepted.");
}

public override async Task ReportsDiagnostics_WhenSettingValueForNonVirtualMemberFromBaseClass(string method, string whenAction)
{
var source = $@"Imports NSubstitute
Namespace MyNamespace
Public MustInherit Class FooBar
Public Function Bar() As Integer
Return 1
End Function
End Class
Public Class Foo
Inherits FooBar
End Class
Public Class FooTests
Public Sub Test()
Dim i As Integer = 1
Dim substitute = NSubstitute.Substitute.[For](Of Foo)()
{method}(substitute,{whenAction}).[Do](Sub(callInfo) i = i + 1)
End Sub
End Class
End Namespace";

await VerifyDiagnostic(source, NonVirtualWhenSetupSpecificationDescriptor, "Member Bar can not be intercepted. Only interface members and overrideable, overriding, and must override members can be intercepted.");
}

public override async Task ReportsNoDiagnostics_WhenSettingValueForVirtualMethod(string method, string whenAction)
{
var source = $@"Imports NSubstitute
Expand Down

0 comments on commit 1f39be9

Please sign in to comment.