diff --git a/src/Compilers/CSharp/Portable/Compiler/DocumentationCommentCompiler.cs b/src/Compilers/CSharp/Portable/Compiler/DocumentationCommentCompiler.cs
index edd5c97d36375..ec6661e4541b2 100644
--- a/src/Compilers/CSharp/Portable/Compiler/DocumentationCommentCompiler.cs
+++ b/src/Compilers/CSharp/Portable/Compiler/DocumentationCommentCompiler.cs
@@ -258,13 +258,7 @@ public override void DefaultVisit(Symbol symbol)
bool shouldSkipPartialDefinitionComments = false;
if (symbol.IsPartialDefinition())
{
- Symbol? implementationPart = symbol switch
- {
- MethodSymbol method => method.PartialImplementationPart,
- SourcePropertySymbol property => property.PartialImplementationPart,
- _ => null
- };
-
+ Symbol? implementationPart = symbol.GetPartialImplementationPart();
if (implementationPart is not null)
{
Visit(implementationPart);
diff --git a/src/Compilers/CSharp/Test/Symbol/DocumentationComments/DocumentationCommentCompilerTests.cs b/src/Compilers/CSharp/Test/Symbol/DocumentationComments/DocumentationCommentCompilerTests.cs
index 29d904d1fc47a..2377b23b1aa4b 100644
--- a/src/Compilers/CSharp/Test/Symbol/DocumentationComments/DocumentationCommentCompilerTests.cs
+++ b/src/Compilers/CSharp/Test/Symbol/DocumentationComments/DocumentationCommentCompilerTests.cs
@@ -2180,6 +2180,1061 @@ void verify(CSharpTestSource source)
}
}
+ [Fact]
+ public void PartialEvent_NoImplementation()
+ {
+ var source = """
+ public partial class C
+ {
+ /** Summary 1 */
+ public partial event System.Action E;
+ }
+ """;
+ var comp = CreateCompilation(source,
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(
+ // (1,22): warning CS1591: Missing XML comment for publicly visible type or member 'C'
+ // public partial class C
+ Diagnostic(ErrorCode.WRN_MissingXMLComment, "C").WithArguments("C").WithLocation(1, 22),
+ // (4,40): error CS9400: Partial member 'C.E' must have an implementation part.
+ // public partial event System.Action E;
+ Diagnostic(ErrorCode.ERR_PartialMemberMissingImplementation, "E").WithArguments("C.E").WithLocation(4, 40));
+ var e = comp.GlobalNamespace.GetMember("C.E");
+
+ AssertEx.AssertEqualToleratingWhitespaceDifferences("""
+
+
+
+ Test
+
+
+
+
+ """, GetDocumentationCommentText(comp,
+ // (1,22): warning CS1591: Missing XML comment for publicly visible type or member 'C'
+ // public partial class C
+ Diagnostic(ErrorCode.WRN_MissingXMLComment, "C").WithArguments("C").WithLocation(1, 22)));
+
+ AssertEx.AssertEqualToleratingWhitespaceDifferences("""
+
+ Summary 1
+
+ """, DocumentationCommentCompiler.GetDocumentationCommentXml(e, processIncludes: true, cancellationToken: default));
+ }
+
+ [Fact]
+ public void PartialConstructor_NoImplementation()
+ {
+ var source = """
+ public partial class C
+ {
+ /** Summary 1 */
+ public partial C();
+ }
+ """;
+ var comp = CreateCompilation(source,
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(
+ // (1,22): warning CS1591: Missing XML comment for publicly visible type or member 'C'
+ // public partial class C
+ Diagnostic(ErrorCode.WRN_MissingXMLComment, "C").WithArguments("C").WithLocation(1, 22),
+ // (4,20): error CS9400: Partial member 'C.C()' must have an implementation part.
+ // public partial C();
+ Diagnostic(ErrorCode.ERR_PartialMemberMissingImplementation, "C").WithArguments("C.C()").WithLocation(4, 20));
+ var ctor = comp.GlobalNamespace.GetMember("C..ctor");
+
+ AssertEx.AssertEqualToleratingWhitespaceDifferences("""
+
+
+
+ Test
+
+
+
+
+ """, GetDocumentationCommentText(comp,
+ // (1,22): warning CS1591: Missing XML comment for publicly visible type or member 'C'
+ // public partial class C
+ Diagnostic(ErrorCode.WRN_MissingXMLComment, "C").WithArguments("C").WithLocation(1, 22)));
+
+ AssertEx.AssertEqualToleratingWhitespaceDifferences("""
+
+ Summary 1
+
+ """, DocumentationCommentCompiler.GetDocumentationCommentXml(ctor, processIncludes: true, cancellationToken: default));
+ }
+
+ [Fact]
+ public void PartialEvent_MultipleFiles()
+ {
+ var source1 = """
+ /** Summary 0 */
+ public partial class C
+ {
+ /** Summary 1 */
+ public partial event System.Action E;
+ }
+ """;
+ var source2 = """
+ public partial class C
+ {
+ /** Summary 2 */
+ public partial event System.Action E { add { } remove { } }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Summary 0
+
+
+ Summary 2
+
+
+
+ """;
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+ }
+
+ [Fact]
+ public void PartialEvent_MultipleFiles_ImplementationComment()
+ {
+ var source1 = """
+ /** Summary 0 */
+ public partial class C
+ {
+ public partial event System.Action E;
+ }
+ """;
+ var source2 = """
+ public partial class C
+ {
+ /** Summary 2 */
+ public partial event System.Action E { add { } remove { } }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Summary 0
+
+
+ Summary 2
+
+
+
+ """;
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+ }
+
+ [Fact]
+ public void PartialEvent_MultipleFiles_DefinitionComment()
+ {
+ var source1 = """
+ /** Summary 0 */
+ public partial class C
+ {
+ /** Summary 1 */
+ public partial event System.Action E;
+ }
+ """;
+ var source2 = """
+ public partial class C
+ {
+ public partial event System.Action E { add { } remove { } }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Summary 0
+
+
+ Summary 1
+
+
+
+ """;
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+ }
+
+ [Fact]
+ public void PartialConstructor_MultipleFiles()
+ {
+ var source1 = """
+ /** Summary 0 */
+ public partial class C
+ {
+ /** Summary 1 */
+ public partial C();
+ }
+ """;
+ var source2 = """
+ public partial class C
+ {
+ /** Summary 2 */
+ public partial C() { }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Summary 0
+
+
+ Summary 2
+
+
+
+ """;
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+ }
+
+ [Fact]
+ public void PartialConstructor_MultipleFiles_ImplementationComment()
+ {
+ var source1 = """
+ /** Summary 0 */
+ public partial class C
+ {
+ public partial C();
+ }
+ """;
+ var source2 = """
+ public partial class C
+ {
+ /** Summary 2 */
+ public partial C() { }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Summary 0
+
+
+ Summary 2
+
+
+
+ """;
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+ }
+
+ [Fact]
+ public void PartialConstructor_MultipleFiles_DefinitionComment()
+ {
+ var source1 = """
+ /** Summary 0 */
+ public partial class C
+ {
+ /** Summary 1 */
+ public partial C();
+ }
+ """;
+ var source2 = """
+ public partial class C
+ {
+ public partial C() { }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Summary 0
+
+
+ Summary 1
+
+
+
+ """;
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+ }
+
+ [Fact]
+ public void PartialEvent_MultipleFiles_NoComment()
+ {
+ var source1 = """
+ /** Summary 0 */
+ public partial class C
+ {
+ public partial event System.Action E;
+ }
+ """;
+ var source2 = """
+ public partial class C
+ {
+ public partial event System.Action E { add { } remove { } }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Summary 0
+
+
+
+ """;
+
+ var expectedDiagnostics = new[]
+ {
+ // (4,40): warning CS1591: Missing XML comment for publicly visible type or member 'C.E'
+ // public partial event System.Action E;
+ Diagnostic(ErrorCode.WRN_MissingXMLComment, "E").WithArguments("C.E").WithLocation(4, 40)
+ };
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp, expectedDiagnostics));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp, expectedDiagnostics));
+ }
+
+ [Fact]
+ public void PartialConstructor_MultipleFiles_NoComment()
+ {
+ var source1 = """
+ /** Summary 0 */
+ public partial class C
+ {
+ public partial C();
+ }
+ """;
+ var source2 = """
+ public partial class C
+ {
+ public partial C() { }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Summary 0
+
+
+
+ """;
+
+ var expectedDiagnostics = new[]
+ {
+ // (4,20): warning CS1591: Missing XML comment for publicly visible type or member 'C.C()'
+ // public partial C();
+ Diagnostic(ErrorCode.WRN_MissingXMLComment, "C").WithArguments("C.C()").WithLocation(4, 20)
+ };
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp, expectedDiagnostics));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp, expectedDiagnostics));
+ }
+
+ [Fact]
+ public void PartialEvent_MultipleFiles_Overlap()
+ {
+ var source1 = """
+ partial class C
+ {
+ /** Summary 1 */
+ public partial event System.Action E;
+ }
+ """;
+ var source2 = """
+ partial class C
+ {
+ /** Remarks 2 */
+ public partial event System.Action E { add { } remove { } }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Remarks 2
+
+
+
+ """;
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics();
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+ }
+
+ [Fact]
+ public void PartialConstructor_MultipleFiles_Overlap()
+ {
+ var source1 = """
+ partial class C
+ {
+ /// Summary 1
+ /// Param 1
+ public partial C(int x, int y);
+ }
+ """;
+ var source2 = """
+ partial class C
+ {
+ /// Remarks 2
+ /// Param 2
+ public partial C(int x, int y) { }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Remarks 2
+ Param 2
+
+
+
+ """;
+
+ var expectedDiagnostics = new[]
+ {
+ // (5,26): warning CS1573: Parameter 'x' has no matching param tag in the XML comment for 'C.C(int, int)' (but other parameters do)
+ // public partial C(int x, int y) { }
+ Diagnostic(ErrorCode.WRN_MissingParamTag, "x").WithArguments("x", "C.C(int, int)").WithLocation(5, 26),
+ // (5,33): warning CS1573: Parameter 'y' has no matching param tag in the XML comment for 'C.C(int, int)' (but other parameters do)
+ // public partial C(int x, int y);
+ Diagnostic(ErrorCode.WRN_MissingParamTag, "y").WithArguments("y", "C.C(int, int)").WithLocation(5, 33)
+ };
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp, expectedDiagnostics));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp, expectedDiagnostics));
+ }
+
+ [Fact]
+ public void PartialEvent_MultipleFiles_InvalidImplComment()
+ {
+ var source1 = """
+ partial class C
+ {
+ /** Summary 1 */
+ public partial event System.Action E;
+ }
+ """;
+ var source2 = """
+ partial class C
+ {
+ /** */
+ public partial event System.Action E { add { } remove { } }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+
+
+ """;
+
+ var expectedDiagnostics = new[]
+ {
+ // (3,20): warning CS1570: XML comment has badly formed XML -- 'End tag 'a' does not match the start tag 'summary'.'
+ // /** */
+ Diagnostic(ErrorCode.WRN_XMLParseError, "a").WithArguments("a", "summary").WithLocation(3, 20),
+ // (3,22): warning CS1570: XML comment has badly formed XML -- 'End tag was not expected at this location.'
+ // /** */
+ Diagnostic(ErrorCode.WRN_XMLParseError, "<").WithLocation(3, 22)
+ };
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+ }
+
+ [Fact]
+ public void PartialConstructor_MultipleFiles_InvalidImplComment()
+ {
+ var source1 = """
+ partial class C
+ {
+ /** Summary 1 */
+ public partial C();
+ }
+ """;
+ var source2 = """
+ partial class C
+ {
+ /** */
+ public partial C() { }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+
+
+ """;
+
+ var expectedDiagnostics = new[]
+ {
+ // (3,20): warning CS1570: XML comment has badly formed XML -- 'End tag 'a' does not match the start tag 'summary'.'
+ // /** */
+ Diagnostic(ErrorCode.WRN_XMLParseError, "a").WithArguments("a", "summary").WithLocation(3, 20),
+ // (3,22): warning CS1570: XML comment has badly formed XML -- 'End tag was not expected at this location.'
+ // /** */
+ Diagnostic(ErrorCode.WRN_XMLParseError, "<").WithLocation(3, 22)
+ };
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+ }
+
+ [Fact]
+ public void PartialEvent_MultipleFiles_InvalidDefComment()
+ {
+ var source1 = """
+ partial class C
+ {
+ /** */
+ public partial event System.Action E;
+ }
+ """;
+ var source2 = """
+ partial class C
+ {
+ /** Summary 2 */
+ public partial event System.Action E { add { } remove { } }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Summary 2
+
+
+
+
+ """;
+
+ var expectedDiagnostics = new[]
+ {
+ // (3,20): warning CS1570: XML comment has badly formed XML -- 'End tag 'a' does not match the start tag 'summary'.'
+ // /** */
+ Diagnostic(ErrorCode.WRN_XMLParseError, "a").WithArguments("a", "summary").WithLocation(3, 20),
+ // (3,22): warning CS1570: XML comment has badly formed XML -- 'End tag was not expected at this location.'
+ // /** */
+ Diagnostic(ErrorCode.WRN_XMLParseError, "<").WithLocation(3, 22)
+ };
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+ }
+
+ [Fact]
+ public void PartialConstructor_MultipleFiles_InvalidDefComment()
+ {
+ var source1 = """
+ partial class C
+ {
+ /** */
+ public partial C();
+ }
+ """;
+ var source2 = """
+ partial class C
+ {
+ /** Summary 2 */
+ public partial C() { }
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Summary 2
+
+
+
+
+ """;
+
+ var expectedDiagnostics = new[]
+ {
+ // (3,20): warning CS1570: XML comment has badly formed XML -- 'End tag 'a' does not match the start tag 'summary'.'
+ // /** */
+ Diagnostic(ErrorCode.WRN_XMLParseError, "a").WithArguments("a", "summary").WithLocation(3, 20),
+ // (3,22): warning CS1570: XML comment has badly formed XML -- 'End tag was not expected at this location.'
+ // /** */
+ Diagnostic(ErrorCode.WRN_XMLParseError, "<").WithLocation(3, 22)
+ };
+
+ var comp = CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ comp = CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments)
+ .VerifyDiagnostics(expectedDiagnostics);
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+ }
+
+ [Fact]
+ public void PartialConstructor_Paramref_01()
+ {
+ var source1 = """
+ partial class C
+ {
+ /** Accepts . */
+ public partial C(int p1) { }
+ }
+ """;
+ var source2 = """
+ partial class C
+ {
+ public partial C(int p2);
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Accepts .
+
+
+
+ """;
+
+ var expectedDiagnostics = new[]
+ {
+ // (4,20): warning CS9256: Partial member declarations 'C.C(int p2)' and 'C.C(int p1)' have signature differences.
+ // public partial C(int p1) { }
+ Diagnostic(ErrorCode.WRN_PartialMemberSignatureDifference, "C").WithArguments("C.C(int p2)", "C.C(int p1)").WithLocation(4, 20)
+ };
+
+ var comp = (CSharpCompilation)CompileAndVerify(CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments),
+ sourceSymbolValidator: validate,
+ symbolValidator: validate)
+ .VerifyDiagnostics(expectedDiagnostics).Compilation;
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ comp = (CSharpCompilation)CompileAndVerify(CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments),
+ sourceSymbolValidator: validate,
+ symbolValidator: validate)
+ .VerifyDiagnostics(expectedDiagnostics).Compilation;
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ static void validate(ModuleSymbol module)
+ {
+ var ctor = module.GlobalNamespace.GetMember("C..ctor");
+ Assert.Equal("p2", ctor.Parameters.Single().Name);
+ }
+ }
+
+ [Fact]
+ public void PartialConstructor_Paramref_02()
+ {
+ var source1 = """
+ partial class C
+ {
+ /** Accepts . */
+ public partial C(int p1) { }
+ }
+ """;
+ var source2 = """
+ partial class C
+ {
+ public partial C(int p2);
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Accepts .
+
+
+
+ """;
+
+ var expectedXmlDiagnostic =
+ // (3,42): warning CS1734: XML comment on 'C.C(int)' has a paramref tag for 'p2', but there is no parameter by that name
+ // /** Accepts . */
+ Diagnostic(ErrorCode.WRN_UnmatchedParamRefTag, "p2").WithArguments("p2", "C.C(int)").WithLocation(3, 42);
+
+ var expectedDiagnostics = new[]
+ {
+ expectedXmlDiagnostic,
+ // (4,20): warning CS9256: Partial member declarations 'C.C(int p2)' and 'C.C(int p1)' have signature differences.
+ // public partial C(int p1) { }
+ Diagnostic(ErrorCode.WRN_PartialMemberSignatureDifference, "C").WithArguments("C.C(int p2)", "C.C(int p1)").WithLocation(4, 20)
+ };
+
+ var comp = (CSharpCompilation)CompileAndVerify(CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments),
+ sourceSymbolValidator: validate,
+ symbolValidator: validate)
+ .VerifyDiagnostics(expectedDiagnostics).Compilation;
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp, expectedXmlDiagnostic));
+
+ comp = (CSharpCompilation)CompileAndVerify(CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments),
+ sourceSymbolValidator: validate,
+ symbolValidator: validate)
+ .VerifyDiagnostics(expectedDiagnostics).Compilation;
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp, expectedXmlDiagnostic));
+
+ static void validate(ModuleSymbol module)
+ {
+ var ctor = module.GlobalNamespace.GetMember("C..ctor");
+ Assert.Equal("p2", ctor.Parameters.Single().Name);
+ }
+ }
+
+ [Fact]
+ public void PartialConstructor_Paramref_03()
+ {
+ var source1 = """
+ partial class C
+ {
+ public partial C(int p1) { }
+ }
+ """;
+ var source2 = """
+ partial class C
+ {
+ /** Accepts . */
+ public partial C(int p2);
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Accepts .
+
+
+
+ """;
+
+ var expectedXmlDiagnostic =
+ // (3,42): warning CS1734: XML comment on 'C.C(int)' has a paramref tag for 'p1', but there is no parameter by that name
+ // /** Accepts . */
+ Diagnostic(ErrorCode.WRN_UnmatchedParamRefTag, "p1").WithArguments("p1", "C.C(int)").WithLocation(3, 42);
+
+ var expectedDiagnostics = new[]
+ {
+ // (3,20): warning CS9256: Partial member declarations 'C.C(int p2)' and 'C.C(int p1)' have signature differences.
+ // public partial C(int p1) { }
+ Diagnostic(ErrorCode.WRN_PartialMemberSignatureDifference, "C").WithArguments("C.C(int p2)", "C.C(int p1)").WithLocation(3, 20),
+ expectedXmlDiagnostic
+ };
+
+ var comp = (CSharpCompilation)CompileAndVerify(CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments),
+ sourceSymbolValidator: validate,
+ symbolValidator: validate)
+ .VerifyDiagnostics(expectedDiagnostics).Compilation;
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp, expectedXmlDiagnostic));
+
+ comp = (CSharpCompilation)CompileAndVerify(CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments),
+ sourceSymbolValidator: validate,
+ symbolValidator: validate)
+ .VerifyDiagnostics(expectedDiagnostics).Compilation;
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp, expectedXmlDiagnostic));
+
+ static void validate(ModuleSymbol module)
+ {
+ var ctor = module.GlobalNamespace.GetMember("C..ctor");
+ Assert.Equal("p2", ctor.Parameters.Single().Name);
+ }
+ }
+
+ [Fact]
+ public void PartialConstructor_Paramref_04()
+ {
+ var source1 = """
+ partial class C
+ {
+ public partial C(int p1) { }
+ }
+ """;
+ var source2 = """
+ partial class C
+ {
+ /** Accepts . */
+ public partial C(int p2);
+ }
+ """;
+
+ var expected = """
+
+
+
+ Test
+
+
+
+ Accepts .
+
+
+
+ """;
+
+ var expectedDiagnostics = new[]
+ {
+ // (3,20): warning CS9256: Partial member declarations 'C.C(int p2)' and 'C.C(int p1)' have signature differences.
+ // public partial C(int p1) { }
+ Diagnostic(ErrorCode.WRN_PartialMemberSignatureDifference, "C").WithArguments("C.C(int p2)", "C.C(int p1)").WithLocation(3, 20)
+ };
+
+ var comp = (CSharpCompilation)CompileAndVerify(CreateCompilation([source1, source2],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments),
+ sourceSymbolValidator: validate,
+ symbolValidator: validate)
+ .VerifyDiagnostics(expectedDiagnostics).Compilation;
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ comp = (CSharpCompilation)CompileAndVerify(CreateCompilation([source2, source1],
+ assemblyName: "Test",
+ parseOptions: TestOptions.RegularPreviewWithDocumentationComments),
+ sourceSymbolValidator: validate,
+ symbolValidator: validate)
+ .VerifyDiagnostics(expectedDiagnostics).Compilation;
+ AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, GetDocumentationCommentText(comp));
+
+ static void validate(ModuleSymbol module)
+ {
+ var ctor = module.GlobalNamespace.GetMember("C..ctor");
+ Assert.Equal("p2", ctor.Parameters.Single().Name);
+ }
+ }
+
#endregion Partial methods
#region Crefs