@@ -226,7 +226,8 @@ public override void VisitNamedType(NamedTypeSymbol symbol)
226226 // 1. visit the type
227227 if ( symbol . IsExtension && ( SourceNamedTypeSymbol ) symbol . ContainingType is { } containingType )
228228 {
229- ImmutableArray < SourceNamedTypeSymbol > extensions = containingType . GetExtensionGroupingInfo ( ) . GetMatchingExtensions ( ( SourceNamedTypeSymbol ) symbol ) ;
229+ // We've been asked to generate the docs for a given extension block. We'll produce the merged docs for the merged blocks.
230+ ImmutableArray < SourceNamedTypeSymbol > extensions = containingType . GetExtensionGroupingInfo ( ) . GetMergedExtensions ( ( SourceNamedTypeSymbol ) symbol ) ;
230231 appendMergedExtensionBlocks ( extensions ) ;
231232 }
232233 else
@@ -264,7 +265,7 @@ void appendContainedExtensions(NamedTypeSymbol containingType)
264265 Debug . Assert ( ! _isForSingleSymbol ) ;
265266 ExtensionGroupingInfo extensionGroupingInfo = ( ( SourceMemberContainerTypeSymbol ) containingType ) . GetExtensionGroupingInfo ( ) ;
266267
267- foreach ( ArrayBuilder < SourceNamedTypeSymbol > extensions in extensionGroupingInfo . EnumerateMergedExtensionBlocks ( ) )
268+ foreach ( ImmutableArray < SourceNamedTypeSymbol > extensions in extensionGroupingInfo . EnumerateMergedExtensionBlocks ( ) )
268269 {
269270 appendMergedExtensionBlocks ( extensions ) ;
270271
@@ -309,8 +310,12 @@ bool collectDocCommentNodes(IEnumerable<SourceNamedTypeSymbol> extensions, Array
309310 {
310311 firstExtension = extension ;
311312 }
313+ else
314+ {
315+ Debug . Assert ( firstExtension . GetEscapedDocumentationCommentId ( ) == extension . GetEscapedDocumentationCommentId ( ) ) ;
316+ }
312317
313- if ( ! TryGetDocumentationCommentNodes ( extension , out var maxDocumentationMode , out var foundDocCommentNodes ) )
318+ if ( ! TryGetDocumentationCommentNodes ( extension , out DocumentationMode maxDocumentationMode , out ImmutableArray < DocumentationCommentTriviaSyntax > foundDocCommentNodes ) )
314319 {
315320 // If the XML in any of the doc comments is invalid, skip all further processing (for this symbol) and
316321 // just write a comment saying that info was lost for this symbol.
@@ -530,10 +535,10 @@ private void ProcessDocumentationCommentTriviaNodes(
530535 {
531536 string ? withUnprocessedIncludes ;
532537 bool haveParseError ;
533- HashSet < TypeParameterSymbol > ? documentedTypeParameters ;
538+ HashSet < string > ? documentedTypeParameterNames ;
534539 HashSet < ParameterSymbol > ? documentedParameters ;
535540 ImmutableArray < CSharpSyntaxNode > includeElementNodes ;
536- if ( ! tryProcessDocumentationCommentTriviaNodes ( symbol , shouldSkipPartialDefinitionComments , docCommentNodes , out withUnprocessedIncludes , out haveParseError , out documentedTypeParameters , out documentedParameters , out includeElementNodes ) )
541+ if ( ! tryProcessDocumentationCommentTriviaNodes ( symbol , shouldSkipPartialDefinitionComments , docCommentNodes , out withUnprocessedIncludes , out haveParseError , out documentedTypeParameterNames , out documentedParameters , out includeElementNodes ) )
537542 {
538543 return ;
539544 }
@@ -557,7 +562,7 @@ private void ProcessDocumentationCommentTriviaNodes(
557562 // the formatting engine would have trouble determining what prefix to remove from each line.
558563 TextWriter ? expanderWriter = shouldSkipPartialDefinitionComments ? null : _writer ; // Don't actually write partial method definition parts.
559564 IncludeElementExpander . ProcessIncludes ( withUnprocessedIncludes , symbol , includeElementNodes ,
560- _compilation , ref documentedParameters , ref documentedTypeParameters , ref _includedFileCache , expanderWriter , _diagnostics , _cancellationToken ) ;
565+ _compilation , ref documentedParameters , ref documentedTypeParameterNames , ref _includedFileCache , expanderWriter , _diagnostics , _cancellationToken ) ;
561566 }
562567 else if ( _writer != null && ! shouldSkipPartialDefinitionComments )
563568 {
@@ -588,14 +593,8 @@ private void ProcessDocumentationCommentTriviaNodes(
588593 }
589594 }
590595
591- if ( documentedTypeParameters != null )
596+ if ( documentedTypeParameterNames != null )
592597 {
593- PooledHashSet < string > documentedTypeParameterNames = PooledHashSet < string > . GetInstance ( ) ;
594- foreach ( var documentedTypeParameter in documentedTypeParameters )
595- {
596- documentedTypeParameterNames . Add ( documentedTypeParameter . Name ) ;
597- }
598-
599598 foreach ( TypeParameterSymbol typeParameter in GetTypeParameters ( symbol ) )
600599 {
601600 if ( ! documentedTypeParameterNames . Contains ( typeParameter . Name ) )
@@ -606,8 +605,6 @@ private void ProcessDocumentationCommentTriviaNodes(
606605 _diagnostics . Add ( ErrorCode . WRN_MissingTypeParamTag , location , typeParameter , symbol ) ;
607606 }
608607 }
609-
610- documentedTypeParameterNames . Free ( ) ;
611608 }
612609 }
613610 return ;
@@ -625,7 +622,7 @@ bool tryProcessDocumentationCommentTriviaNodes(
625622 ImmutableArray < DocumentationCommentTriviaSyntax > docCommentNodes ,
626623 [ NotNullWhen ( true ) ] out string ? withUnprocessedIncludes ,
627624 out bool haveParseError ,
628- out HashSet < TypeParameterSymbol > ? documentedTypeParameters ,
625+ out HashSet < string > ? documentedTypeParameterNames ,
629626 out HashSet < ParameterSymbol > ? documentedParameters ,
630627 out ImmutableArray < CSharpSyntaxNode > includeElementNodes )
631628 {
@@ -636,7 +633,7 @@ bool tryProcessDocumentationCommentTriviaNodes(
636633 ArrayBuilder < CSharpSyntaxNode > ? includeElementNodesBuilder = null ;
637634
638635 documentedParameters = null ;
639- documentedTypeParameters = null ;
636+ documentedTypeParameterNames = null ;
640637
641638 // Saw an XmlException while parsing one of the DocumentationCommentTriviaSyntax nodes.
642639 haveParseError = false ;
@@ -678,7 +675,7 @@ bool tryProcessDocumentationCommentTriviaNodes(
678675
679676 // Will respect the DocumentationMode.
680677 string substitutedText = DocumentationCommentWalker . GetSubstitutedText ( _compilation , _diagnostics , symbol , trivia ,
681- includeElementNodesBuilder , ref documentedParameters , ref documentedTypeParameters ) ;
678+ includeElementNodesBuilder , ref documentedParameters , ref documentedTypeParameterNames ) ;
682679
683680 string formattedXml = FormatComment ( substitutedText ) ;
684681
@@ -1260,7 +1257,7 @@ private static void BindName(
12601257 Binder binder ,
12611258 Symbol memberSymbol ,
12621259 ref HashSet < ParameterSymbol > documentedParameters ,
1263- ref HashSet < TypeParameterSymbol > documentedTypeParameters ,
1260+ ref HashSet < string > documentedTypeParameterNames ,
12641261 BindingDiagnosticBag diagnostics )
12651262 {
12661263 XmlNameAttributeElementKind elementKind = syntax . GetElementKind ( ) ;
@@ -1277,9 +1274,9 @@ private static void BindName(
12771274 }
12781275 else if ( elementKind == XmlNameAttributeElementKind . TypeParameter )
12791276 {
1280- if ( documentedTypeParameters == null )
1277+ if ( documentedTypeParameterNames == null )
12811278 {
1282- documentedTypeParameters = new HashSet < TypeParameterSymbol > ( ) ;
1279+ documentedTypeParameterNames = new HashSet < string > ( ) ;
12831280 }
12841281 }
12851282
@@ -1335,9 +1332,9 @@ private static void BindName(
13351332 else if ( elementKind == XmlNameAttributeElementKind . TypeParameter )
13361333 {
13371334 Debug . Assert ( referencedSymbol . Kind == SymbolKind . TypeParameter ) ;
1338- Debug . Assert ( documentedTypeParameters != null ) ;
1335+ Debug . Assert ( documentedTypeParameterNames != null ) ;
13391336
1340- if ( ! documentedTypeParameters . Add ( ( TypeParameterSymbol ) referencedSymbol ) )
1337+ if ( ! documentedTypeParameterNames . Add ( ( ( TypeParameterSymbol ) referencedSymbol ) . Name ) )
13411338 {
13421339 diagnostics . Add ( ErrorCode . WRN_DuplicateTypeParamTag , syntax . Location , identifier ) ;
13431340 }
0 commit comments