Skip to content
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Drop support for Visual Studio 2022 VSIX ([PR](https://github.com/dotnet/roslynator/pull/1787))
- Pin last 4.x release ([Roslynator 2022](https://marketplace.visualstudio.com/items?itemName=josefpihrt.Roslynator2022)) or use NuGet packages on Visual Studio 2022

### Fixed

- Fix analyzers [RCS1263](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1263) and [RCS1139](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1139) for C# 14 extension block documentation ([PR](https://github.com/dotnet/roslynator/pull/1799))

## [4.16.1] - 2026-08-16

### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,18 @@ private static void AnalyzeSingleLineDocumentationCommentTrivia(SyntaxNodeAnalys
return;
}

SyntaxNode parent = documentationComment.ParentTrivia.Token.Parent;

if (!containsSummaryElement
&& !containsContentElement)
&& !containsContentElement
#if ROSLYN_5_0
&& parent?.IsKind(SyntaxKind.ExtensionBlockDeclaration) != true
#endif
)
{
ReportDiagnosticIfEffective(context, DiagnosticRules.AddSummaryElementToDocumentationComment, documentationComment);
}

SyntaxNode parent = documentationComment.ParentTrivia.Token.Parent;

bool invalidReference = DiagnosticRules.InvalidReferenceInDocumentationComment.IsEffective(context);
bool orderParams = DiagnosticRules.OrderElementsInDocumentationComment.IsEffective(context);
bool addParam = DiagnosticRules.AddParamElementToDocumentationComment.IsEffective(context);
Expand Down
8 changes: 8 additions & 0 deletions src/CSharp/CSharp/CSharpUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,10 @@ public static SeparatedSyntaxList<ParameterSyntax> GetParameters(SyntaxNode decl
case SyntaxKind.StructDeclaration:
case SyntaxKind.InterfaceDeclaration:
return ((TypeDeclarationSyntax)declaration).ParameterList;
#endif
#if ROSLYN_5_0
case SyntaxKind.ExtensionBlockDeclaration:
return ((ExtensionBlockDeclarationSyntax)declaration).ParameterList;
#endif
default:
return null;
Expand Down Expand Up @@ -720,6 +724,10 @@ public static SeparatedSyntaxList<TypeParameterSyntax> GetTypeParameters(SyntaxN
case SyntaxKind.RecordStructDeclaration:
#endif
return ((RecordDeclarationSyntax)declaration).TypeParameterList;
#if ROSLYN_5_0
case SyntaxKind.ExtensionBlockDeclaration:
return ((ExtensionBlockDeclarationSyntax)declaration).TypeParameterList;
#endif
default:
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,20 @@ partial class C
}
");
}

[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.AddSummaryElementToDocumentationComment)]
public async Task TestNoDiagnostic_ExtensionBlock_WithoutSummary()
{
await VerifyNoDiagnosticAsync("""
static class C
{
/// <param name="x">x</param>
/// <typeparam name="T">T</typeparam>
extension<T>(T x) where T : struct
{
public int M() => 0;
}
}
""");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,47 @@ public struct Foo(string value)
{
public string Value { get; } = value;
}
""");
}

[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.InvalidReferenceInDocumentationComment)]
public async Task TestNoDiagnostic_ExtensionBlock_ParamAndTypeParam()
{
await VerifyNoDiagnosticAsync("""
static class C
{
/// <param name="x">x</param>
/// <typeparam name="T">T</typeparam>
extension<T>(T x) where T : struct
{
public int M() => 0;
}
Comment thread
josefpihrt marked this conversation as resolved.
}
""");
}

[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.InvalidReferenceInDocumentationComment)]
public async Task Test_ExtensionBlock_InvalidParamName()
{
await VerifyDiagnosticAndFixAsync("""
static class C
{
/// <param name="[|missing|]"></param>
/// <typeparam name="T">T</typeparam>
extension<T>(T x) where T : struct
{
public int M() => 0;
}
}
""", """
static class C
{
/// <typeparam name="T">T</typeparam>
extension<T>(T x) where T : struct
{
public int M() => 0;
}
}
""");
}
}
Loading