Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update SA1648 to accept inheritdoc on members implemented from static abstract/virtual interface members #3715

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,46 @@

namespace StyleCop.Analyzers.Test.CSharp11.DocumentationRules
{
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using StyleCop.Analyzers.Test.CSharp10.DocumentationRules;
using Xunit;

public partial class SA1648CSharp11UnitTests : SA1648CSharp10UnitTests
{
[WorkItem(3595, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3595")]
[Theory]
[InlineData("abstract void TestMethod();", "public void TestMethod() {}")]
[InlineData("abstract void TestMethod();", "void TestInterface.TestMethod() {}")]
[InlineData("virtual void TestMethod() {}", "public void TestMethod() {}")]
[InlineData("virtual void TestMethod() {}", "void TestInterface.TestMethod() {}")]
[InlineData("abstract int TestProperty { get; set; }", "public int TestProperty { get; set; }")]
[InlineData("abstract int TestProperty { get; set; }", "int TestInterface.TestProperty { get; set; }")]
[InlineData("virtual int TestProperty { get; set; }", "public int TestProperty { get; set; }")]
[InlineData("virtual int TestProperty { get; set; }", "int TestInterface.TestProperty { get; set; }")]
[InlineData("abstract event System.Action TestEvent;", "public event System.Action TestEvent;")]
[InlineData("abstract event System.Action TestEvent;", "event System.Action TestInterface.TestEvent { add {} remove {} }")]
[InlineData("virtual event System.Action TestEvent;", "public event System.Action TestEvent;")]
[InlineData("virtual event System.Action TestEvent;", "event System.Action TestInterface.TestEvent { add {} remove {} }")]
public async Task TestCorrectMemberInheritDocFromStaticAbstractOrVirtualMemberInInterfaceAsync(string interfaceMember, string classMember)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Can we also test explicit interface implementations?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

{
var testCode = $@"
public interface TestInterface
{{
/// <summary>
/// A summary text.
/// </summary>
static {interfaceMember}
}}

public class TestClass : TestInterface
{{
/// <inheritdoc />
static {classMember}
}}";

await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,37 @@

namespace StyleCop.Analyzers.Test.CSharp8.DocumentationRules
{
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using StyleCop.Analyzers.Test.CSharp7.DocumentationRules;
using Xunit;

public partial class SA1648CSharp8UnitTests : SA1648CSharp7UnitTests
{
[WorkItem(3595, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3595")]
[Theory]
[InlineData("void TestMethod() {}")]
[InlineData("int TestProperty { get; set; }")]
[InlineData("event System.Action TestEvent;")]
public async Task TestIncorrectMemberInheritDocFromStaticMemberInInterfaceAsync(string member)
{
var testCode = $@"
public interface TestInterface
{{
/// <summary>
/// A summary text.
/// </summary>
static {member}
}}

public class TestClass : TestInterface
{{
/// [|<inheritdoc />|]
public static {member}
}}";

await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,10 @@ public async Task TestIncorrectDelegateInheritDocAsync()
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
}

private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult expected, CancellationToken cancellationToken)
protected static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult expected, CancellationToken cancellationToken)
=> VerifyCSharpDiagnosticAsync(source, new[] { expected }, cancellationToken);

private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult[] expected, CancellationToken cancellationToken)
protected static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult[] expected, CancellationToken cancellationToken)
{
var test = CreateTest(expected);
test.TestCode = source;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,6 @@ internal static bool IsPartialDeclaration(MemberDeclarationSyntax declaration)
/// <returns>true if the member is implementing an interface member, otherwise false.</returns>
internal static bool IsImplementingAnInterfaceMember(ISymbol memberSymbol)
{
if (memberSymbol.IsStatic)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this was just an optimization that can no longer remain, at least not in this simple form

{
return false;
}

bool isImplementingExplicitly;

// Only methods, properties and events can implement an interface member
Expand Down