9
9
using Microsoft . CodeAnalysis ;
10
10
using Microsoft . CodeAnalysis . CSharp ;
11
11
using Microsoft . CodeAnalysis . CSharp . Syntax ;
12
+ using static System . Net . Mime . MediaTypeNames ;
12
13
13
14
namespace ApiDocsSync . PortToTripleSlash . Roslyn ;
14
15
@@ -33,7 +34,7 @@ public DocumentationUpdater(Configuration config, IDocsAPI api, SyntaxTrivia? in
33
34
34
35
public DocumentationCommentTriviaSyntax GetUpdatedDocs ( SyntaxList < XmlNodeSyntax > originalDocumentation )
35
36
{
36
- SyntaxList < XmlNodeSyntax > docsNodes = SyntaxFactory . List < XmlNodeSyntax > ( ) ;
37
+ List < XmlNodeSyntax > docsNodes = [ ] ;
37
38
38
39
// Preserve the order in which each API element is looked for below
39
40
@@ -43,7 +44,7 @@ public DocumentationCommentTriviaSyntax GetUpdatedDocs(SyntaxList<XmlNodeSyntax>
43
44
}
44
45
else if ( TryGet ( "summary" ) is XmlNodeSyntax existingSummary )
45
46
{
46
- docsNodes . Add ( existingSummary ) ;
47
+ docsNodes . AddRange ( RegeneraGetFullTripleSlashXmlSyntaxNodeteExistingNode ( existingSummary ) ) ;
47
48
}
48
49
49
50
foreach ( DocsTypeParam typeParam in _api . TypeParams )
@@ -54,7 +55,7 @@ public DocumentationCommentTriviaSyntax GetUpdatedDocs(SyntaxList<XmlNodeSyntax>
54
55
}
55
56
else if ( TryGet ( "typeparam" , "name" , typeParam . Value ) is XmlNodeSyntax existingTypeParam )
56
57
{
57
- docsNodes . Add ( existingTypeParam ) ;
58
+ docsNodes . AddRange ( GetFullTripleSlashXmlSyntaxNode ( existingTypeParam ) ) ;
58
59
59
60
}
60
61
}
@@ -67,7 +68,7 @@ public DocumentationCommentTriviaSyntax GetUpdatedDocs(SyntaxList<XmlNodeSyntax>
67
68
}
68
69
else if ( TryGet ( "param" , "name" , param . Value ) is XmlNodeSyntax existingParam )
69
70
{
70
- docsNodes . Add ( existingParam ) ;
71
+ docsNodes . AddRange ( GetFullTripleSlashXmlSyntaxNode ( existingParam ) ) ;
71
72
72
73
}
73
74
}
@@ -78,16 +79,19 @@ public DocumentationCommentTriviaSyntax GetUpdatedDocs(SyntaxList<XmlNodeSyntax>
78
79
}
79
80
else if ( TryGet ( "returns" ) is XmlNodeSyntax existingReturns )
80
81
{
81
- docsNodes . Add ( existingReturns ) ;
82
+ docsNodes . AddRange ( GetFullTripleSlashXmlSyntaxNode ( existingReturns ) ) ;
82
83
}
83
84
84
- if ( ! _config . SkipRemarks && ! _api . Remarks . IsDocsEmpty ( ) )
85
+ if ( ! _config . SkipRemarks )
85
86
{
86
- docsNodes . AddRange ( GetRemarksNodes ( ) ) ;
87
- }
88
- else if ( TryGet ( "remarks" ) is XmlNodeSyntax existingRemarks )
89
- {
90
- docsNodes . Add ( existingRemarks ) ;
87
+ if ( ! _api . Remarks . IsDocsEmpty ( ) )
88
+ {
89
+ docsNodes . AddRange ( GetRemarksNodes ( ) ) ;
90
+ }
91
+ else if ( TryGet ( "remarks" ) is XmlNodeSyntax existingRemarks )
92
+ {
93
+ docsNodes . AddRange ( GetFullTripleSlashXmlSyntaxNode ( existingRemarks ) ) ;
94
+ }
91
95
}
92
96
93
97
foreach ( DocsException exception in _api . Exceptions )
@@ -98,14 +102,14 @@ public DocumentationCommentTriviaSyntax GetUpdatedDocs(SyntaxList<XmlNodeSyntax>
98
102
}
99
103
else if ( TryGet ( "exception" , "cref" , exception . Value ) is XmlNodeSyntax existingException )
100
104
{
101
- docsNodes . Add ( existingException ) ;
105
+ docsNodes . AddRange ( GetFullTripleSlashXmlSyntaxNode ( existingExceptio
10000
n ) ) ;
102
106
103
107
}
104
108
}
105
109
106
110
return SyntaxFactory . DocumentationCommentTrivia (
107
111
SyntaxKind . SingleLineDocumentationCommentTrivia ,
108
- docsNodes ) ;
112
+ SyntaxFactory . List ( docsNodes ) ) ;
109
113
110
114
XmlNodeSyntax ? TryGet ( string tagName , string ? attributeName = null , string ? attributeValue = null )
111
115
{
@@ -115,19 +119,20 @@ public DocumentationCommentTriviaSyntax GetUpdatedDocs(SyntaxList<XmlNodeSyntax>
115
119
116
120
public DocumentationCommentTriviaSyntax GetNewDocs ( )
117
121
{
118
- SyntaxList < XmlNodeSyntax > docsNodes = SyntaxFactory . List < XmlNodeSyntax > ( ) ;
119
-
120
- // Preserve the order
121
- docsNodes . AddRange ( GetSummaryNodes ( ) ) ;
122
- docsNodes . AddRange ( GetTypeParamNodes ( ) ) ;
123
- docsNodes . AddRange ( GetParamNodes ( ) ) ;
124
- docsNodes . AddRange ( GetReturnsNodes ( ) ) ;
125
- docsNodes . AddRange ( GetRemarksNodes ( ) ) ;
126
- docsNodes . AddRange ( GetExceptionNodes ( ) ) ;
122
+ List < XmlNodeSyntax > docsNodes =
123
+ [
124
+ // Preserve the order
125
+ .. GetSummaryNodes ( ) ,
126
+ .. GetTypeParamNodes ( ) ,
127
+ .. GetParamNodes ( ) ,
128
+ .. GetReturnsNodes ( ) ,
129
+ .. GetRemarksNodes ( ) ,
130
+ .. GetExceptionNodes ( ) ,
131
+ ] ;
127
132
128
133
return SyntaxFactory . DocumentationCommentTrivia (
129
134
SyntaxKind . SingleLineDocumentationCommentTrivia ,
130
- docsNodes ) ;
135
+ SyntaxFactory . List ( docsNodes ) ) ;
131
136
}
132
137
133
138
private XmlNodeSyntax [ ] GetSummaryNodes ( )
@@ -137,16 +142,16 @@ private XmlNodeSyntax[] GetSummaryNodes()
137
142
return [ ] ;
138
143
}
139
144
140
- SyntaxList < XmlNodeSyntax > internalTextNodes = SyntaxFactory . List < XmlNodeSyntax > ( ) ;
145
+ List < XmlNodeSyntax > internalTextNodes = new ( ) ;
141
146
foreach ( string line in _api . Summary . Split ( _NewLineSeparators , _NewLineSplitOptions ) )
142
147
{
143
- internalTextNodes . Add ( GetTripleSlashSingleLineXmlTextSyntaxNode ( _indentationTrivia , line ) ) ;
148
+ internalTextNodes . Add ( GetFullTripleSlashSingleLineXmlTextSyntaxNode ( line ) ) ;
144
149
}
145
150
146
151
return [
147
152
GetTripleSlashTextSyntaxNode ( ) ,
148
- SyntaxFactory . XmlSummaryElement ( internalTextNodes ) ,
149
- GetNewLineTextSyntaxNode ( ) ,
153
+ SyntaxFactory . XmlSummaryElement ( internalTextNodes . ToArray ( ) ) . WithEndTag ( endTag ) , // TODO
154
+ GetNewLineTextSyntaxNode ( )
150
155
] ;
151
156
}
152
157
@@ -157,7 +162,7 @@ private XmlNodeSyntax[] GetTypeParamNodes()
157
162
return [ ] ;
158
163
}
159
164
160
- SyntaxList < XmlNodeSyntax > typeParamNodes = SyntaxFactory . List < XmlNodeSyntax > ( ) ;
165
+ List < XmlNodeSyntax > typeParamNodes = new ( ) ;
161
166
foreach ( DocsTypeParam typeParam in _api . TypeParams )
162
167
{
163
168
typeParamNodes . AddRange ( GetTypeParamNode ( typeParam ) ) ;
@@ -168,17 +173,14 @@ private XmlNodeSyntax[] GetTypeParamNodes()
168
173
169
174
private XmlNodeSyntax [ ] GetTypeParamNode ( DocsTypeParam typeParam )
170
175
{
171
- SyntaxList < XmlNodeSyntax > internalTextNodes = SyntaxFactory . List < XmlNodeSyntax > ( ) ;
176
+ List < XmlNodeSyntax > internalTextNodes = new ( ) ;
172
177
foreach ( string line in typeParam . Value . Split ( _NewLineSeparators , _NewLineSplitOptions ) )
173
178
{
174
- internalTextNodes . Add ( GetTripleSlashSingleLineXmlTextSyntaxNode ( _indentationTrivia , line ) ) ;
179
+ internalTextNodes . Add ( GetFullTripleSlashSingleLineXmlTextSyntaxNode ( line ) ) ;
175
180
}
176
181
177
- return [
178
- GetTripleSlashTextSyntaxNode ( ) ,
179
- GetXmlAttributedElement ( internalTextNodes , "typeparam" , "name" , typeParam . Name ) ,
180
- GetNewLineTextSyntaxNode ( )
181
- ] ;
182
+ // TODO
183
+ return GetFullTripleSlashXmlSyntaxNode ( GetXmlAttributedElement ( internalTextNodes , "typeparam" , "name" , typeParam . Name ) ) ;
182
184
}
183
185
184
186
private XmlNodeSyntax [ ] GetParamNodes ( )
@@ -188,7 +190,7 @@ private XmlNodeSyntax[] GetParamNodes()
188
190
return [ ] ;
189
191
}
190
192
191
- SyntaxList < XmlNodeSyntax > paramNodes = SyntaxFactory . List < XmlNodeSyntax > ( ) ;
193
+ List < XmlNodeSyntax > paramNodes = new ( ) ;
192
194
foreach ( DocsParam param in _api . Params )
193
195
{
194
196
paramNodes . AddRange ( GetParamNode ( param ) ) ;
@@ -202,7 +204,7 @@ private XmlNodeSyntax[] GetParamNode(DocsParam param)
202
204
SyntaxList < XmlNodeSyntax > internalTextNodes = SyntaxFactory . List < XmlNodeSyntax > ( ) ;
203
205
foreach ( string line in param . Value . Split ( _NewLineSeparators , _NewLineSplitOptions ) )
204
206
{
205
- internalTextNodes . Add ( GetTripleSlashSingleLineXmlTextSyntaxNode ( _indentationTrivia , line ) ) ;
207
+ internalTextNodes . Add ( GetFullTripleSlashSingleLineXmlTextSyntaxNode ( line ) ) ;
206
208
}
207
209
208
210
return [
@@ -219,15 +221,15 @@ private XmlNodeSyntax[] GetReturnsNodes()
219
221
return [ ] ;
220
222
}
221
223
222
- SyntaxList < XmlNodeSyntax > internalTextNodes = SyntaxFactory . List < XmlNodeSyntax > ( ) ;
224
+ List < XmlNodeSyntax > internalTextNodes = new ( ) ;
223
225
foreach ( string line in _api . Returns . Split ( _NewLineSeparators , _NewLineSplitOptions ) )
224
226
{
225
- internalTextNodes . Add ( GetTripleSlashSingleLineXmlTextSyntaxNode ( _indentationTrivia , line ) ) ;
227
+ internalTextNodes . Add ( GetFullTripleSlashSingleLineXmlTextSyntaxNode ( line ) ) ;
226
228
}
227
229
228
230
return [
229
231
GetTripleSlashTextSyntaxNode ( ) ,
230
- SyntaxFactory . XmlReturnsElement ( internalTextNodes ) ,
232
+ SyntaxFactory . XmlReturnsElement ( internalTextNodes . ToArray ( ) ) ,
231
233
GetNewLineTextSyntaxNode ( ) ,
232
234
] ;
233
235
}
@@ -239,15 +241,15 @@ private XmlNodeSyntax[] GetRemarksNodes()
239
241
return [ ] ;
240
242
}
241
243
242
- SyntaxList < XmlNodeSyntax > internalTextNodes = SyntaxFactory . List < XmlNodeSyntax > ( ) ;
244
+ List < XmlNodeSyntax > internalTextNodes = new ( ) ;
243
245
foreach ( string line in _api . Remarks . Split ( _NewLineSeparators , _NewLineSplitOptions ) )
244
246
{
245
- internalTextNodes . Add ( GetTripleSlashSingleLineXmlTextSyntaxNode ( _indentationTrivia , line ) ) ;
247
+ internalTextNodes . Add ( GetFullTripleSlashSingleLineXmlTextSyntaxNode ( line ) ) ;
246
248
}
247
249
248
250
return [
249
251
GetTripleSlashTextSyntaxNode ( ) ,
250
- SyntaxFactory . XmlRemarksElement ( internalTextNodes ) ,
252
+ SyntaxFactory . XmlRemarksElement ( internalTextNodes . ToArray ( ) ) ,
251
253
GetNewLineTextSyntaxNode ( ) ,
252
254
] ;
253
255
}
@@ -259,7 +261,7 @@ private XmlNodeSyntax[] GetExceptionNodes()
259
261
return [ ] ;
260
262
}
261
263
262
- SyntaxList < XmlNodeSyntax > exceptionNodes = SyntaxFactory . List < XmlNodeSyntax > ( ) ;
264
+ List < XmlNodeSyntax > exceptionNodes = new ( ) ;
263
265
foreach ( DocsException exception in _api . Exceptions )
264
266
{
265
267
exceptionNodes . AddRange ( GetExceptionNode ( exception ) ) ;
@@ -273,7 +275,7 @@ private XmlNodeSyntax[] GetExceptionNode(DocsException exception)
273
275
SyntaxList < XmlNodeSyntax > internalTextNodes = SyntaxFactory . List < XmlNodeSyntax > ( ) ;
274
276
foreach ( string line in exception . Value . Split ( _NewLineSeparators , _NewLineSplitOptions ) )
275
277
{
276
- internalTextNodes . Add ( GetTripleSlashSingleLineXmlTextSyntaxNode ( _indentationTrivia , line ) ) ;
278
+ internalTextNodes . Add ( GetFullTripleSlashSingleLineXmlTextSyntaxNode ( line ) ) ;
277
279
}
278
280
279
281
return [
@@ -289,8 +291,6 @@ private XmlElementSyntax GetXmlAttributedElement(IEnumerable<XmlNodeSyntax> cont
289
291
Debug . Assert ( ! string . IsNullOrWhiteSpace ( attributeName ) ) ;
290
292
Debug . Assert ( ! string . IsNullOrWhiteSpace ( attributeValue ) ) ;
291
293
292
- XmlElementStartTagSyntax startTag = SyntaxFactory . XmlElementStartTag ( SyntaxFactory . XmlName ( SyntaxFactory . Identifier ( tagName ) ) ) ;
293
-
294
294
SyntaxToken xmlAttributeName = SyntaxFactory . Identifier (
295
295
leading : SyntaxFactory . TriviaList ( SyntaxFactory . Space ) ,
296
296
text : attributeName ,
@@ -302,69 +302,96 @@ private XmlElementSyntax GetXmlAttributedElement(IEnumerable<XmlNodeSyntax> cont
302
302
identifier : SyntaxFactory . IdentifierName ( attributeValue ) ,
303
303
endQuoteToken : SyntaxFactory . Token ( SyntaxKind . DoubleQuoteToken ) ) ;
304
304
305
- SyntaxList < XmlAttributeSyntax > startTagAttributes = SyntaxFactory . SingletonList < XmlAttributeSyntax > ( xmlAttribute ) ;
306
-
307
- startTag = startTag . WithAttributes ( startTagAttributes ) ;
305
+ XmlElementStartTagSyntax startTag = SyntaxFactory
306
+ . XmlElementStartTag ( SyntaxFactory . XmlName ( SyntaxFactory . Identifier ( tagName ) ) )
307
+ . WithAttributes ( SyntaxFactory . List < XmlAttributeSyntax > ( [ xmlAttribute ] ) ) ;
308
308
309
309
XmlElementEndTagSyntax endTag = SyntaxFactory . XmlElementEndTag ( SyntaxFactory . XmlName ( SyntaxFactory . Identifier ( tagName ) ) ) ;
310
310
311
311
return SyntaxFactory . XmlElement ( startTag , SyntaxFactory . List ( content ) , endTag ) ;
312
312
}
313
313
314
+ private XmlNodeSyntax [ ] GetFullTripleSlashXmlSyntaxNode ( XmlNodeSyntax existingNode )
315
+ {
316
+ GetIndentationSyntaxToken ( out SyntaxToken indentationSyntaxToken ) ;
317
+ GetTripleSlashSyntaxToken ( out SyntaxToken tripleSlashSyntaxToken ) ;
318
+ GetNewLineSyntaxToken ( out SyntaxToken newLineSyntaxToken ) ;
319
+
320
+ return [
321
+ SyntaxFactory . XmlText ( new SyntaxToken [ ] { indentationSyntaxToken , tripleSlashSyntaxToken } ) ,
322
+ existingNode ,
323
+ SyntaxFactory . XmlText ( SyntaxFactory . TokenList ( newLineSyntaxToken ) ) ,
324
+ ] ;
325
+ }
326
+
314
327
// Returns a single line of triple slash comments plus the optional line of text that may follow it.
315
328
// [indentation][tripleslash][textline][newline]
316
329
// Example: ->->->/// text\n
317
- private XmlTextSyntax GetTripleSlashSingleLineXmlTextSyntaxNode ( SyntaxTrivia ? indentationTrivia , string ? text = null )
330
+ private XmlTextSyntax GetFullTripleSlashSingleLineXmlTextSyntaxNode ( string text )
318
331
{
319
- SyntaxTokenList syntaxTokenList = SyntaxFactory . TokenList ( ) ;
320
-
321
- syntaxTokenList . Add ( GetIndentationSyntaxToken ( indentationTrivia ) ) ;
322
- syntaxTokenList . Add ( GetTripleSlashSyntaxToken ( ) ) ;
323
- if ( text != null )
324
- {
325
- syntaxTokenList . Add ( SyntaxFactory . XmlTextNewLine (
332
+ GetIndentationSyntaxToken ( out SyntaxToken indentationSyntaxToken ) ;
333
+ GetTripleSlashSyntaxToken ( out SyntaxToken tripleSlashSyntaxToken ) ;
334
+ GetNewLineSyntaxToken ( out SyntaxToken newLineSyntaxToken ) ;
335
+
336
+ SyntaxToken [ ] syntaxTokenList = [
337
+ indentationSyntaxToken ,
338
+ tripleSlashSyntaxToken ,
339
+ SyntaxFactory . XmlTextNewLine (
326
340
leading : SyntaxFactory . TriviaList ( ) ,
327
341
text : text ,
328
342
value : text ,
329
- trailing : SyntaxFactory . TriviaList ( ) ) ) ;
330
- }
331
- syntaxTokenList . Add ( GetNewLineSyntaxToken ( ) ) ;
343
+ trailing : SyntaxFactory . TriviaList ( ) ) ,
344
+ newLineSyntaxToken
345
+ ] ;
332
346
333
- return SyntaxFactory . XmlText ( ) . WithTextTokens ( syntaxTokenList ) ;
347
+ return SyntaxFactory . XmlText ( SyntaxFactory . TokenList ( syntaxTokenList ) ) ;
334
348
}
335
349
336
350
// Returns a syntax node containing the "/// " text literal syntax token.
337
- private XmlTextSyntax GetTripleSlashTextSyntaxNode ( ) =>
338
- SyntaxFactory . XmlText ( ) . WithTextTokens ( SyntaxFactory . TokenList ( GetTripleSlashSyntaxToken ( ) ) ) ;
351
+ private XmlTextSyntax GetTripleSlashTextSyntaxNode ( )
352
+ {
353
+ GetTripleSlashSyntaxToken ( out SyntaxToken tripleSlashSyntaxToken ) ;
354
+ return SyntaxFactory . XmlText ( ) . WithTextTokens ( SyntaxFactory . TokenList ( tripleSlashSyntaxToken ) ) ;
355
+ }
339
356
340
357
// Returns a syntax node containing the "\n" text literal syntax token.
341
- private XmlTextSyntax GetNewLineTextSyntaxNode ( ) =>
342
- SyntaxFactory . XmlText ( ) . WithTextTokens ( SyntaxFactory . TokenList ( GetNewLineSyntaxToken ( ) ) ) ;
358
+ private XmlTextSyntax GetNewLineTextSyntaxNode ( )
359
+ {
360
+ GetNewLineSyntaxToken ( out SyntaxToken newLineSyntaxToken ) ;
361
+ return SyntaxFactory . XmlText ( ) . WithTextTokens ( SyntaxFactory . TokenList ( newLineSyntaxToken ) ) ;
362
+ }
343
363
344
- // Returns a syntax token with the "" text literal preceded by the specified indentation trivia.
345
- private SyntaxToken GetIndentationSyntaxToken ( SyntaxTrivia ? indentationTrivia ) =>
346
- SyntaxFactory . XmlTextLiteral (
347
- leading : indentationTrivia != null ? SyntaxFactory . TriviaList ( indentationTrivia . Value ) : SyntaxFactory . TriviaList ( ) ,
348
- text : string . Empty ,
349
- value : string . Empty ,
350
- trailing : SyntaxFactory . TriviaList ( ) ) ;
364
+ // Returns a syntax node containing the specified indentation text literal syntax token.
365
+ private XmlTextSyntax GetIndentationTextSyntaxNode ( )
366
+ {
367
+ GetIndentationSyntaxToken ( out SyntaxToken indentationSyntaxToken ) ;
368
+ return SyntaxFactory . XmlText ( ) . WithTextTokens ( SyntaxFactory . TokenList ( indentationSyntaxToken ) ) ;
369
+ }
351
370
352
371
// Returns a syntax token containing the "/// " text literal.
353
- private SyntaxToken GetTripleSlashSyntaxToken ( ) =>
354
- SyntaxFactory . XmlTextLiteral (
372
+ private void GetTripleSlashSyntaxToken ( out SyntaxToken tripleSlashSyntaxToken ) =>
373
+ tripleSlashSyntaxToken = SyntaxFactory . XmlTextLiteral (
355
374
leading : SyntaxFactory . TriviaList ( SyntaxFactory . DocumentationCommentExterior ( TripleSlash ) ) ,
356
375
text : Space ,
357
376
value : Space ,
358
377
trailing : SyntaxFactory . TriviaList ( ) ) ;
359
378
360
379
// Returns a syntax token containing the "\n" text literal.
361
- private SyntaxToken GetNewLineSyntaxToken ( ) =>
362
- SyntaxFactory . XmlTextNewLine (
380
+ private void GetNewLineSyntaxToken ( out SyntaxToken newLineSyntaxToken ) =>
381
+ newLineSyntaxToken = SyntaxFactory . XmlTextNewLine (
363
382
leading : SyntaxFactory . TriviaList ( ) ,
364
383
text : NewLine ,
365
384
value : NewLine ,
366
385
trailing : SyntaxFactory . TriviaList ( ) ) ;
367
386
387
+ // Returns a syntax token with the "" text literal preceded by the specified indentation trivia.
388
+ private void GetIndentationSyntaxToken ( out SyntaxToken indentationSyntaxToken ) =>
389
+ indentationSyntaxToken = SyntaxFactory . XmlTextLiteral (
390
+ leading : SyntaxFactory . TriviaList ( _indentationTrivia ) ,
391
+ text : string . Empty ,
392
+ value : string . Empty ,
393
+ trailing : SyntaxFactory . TriviaList ( ) ) ;
394
+
368
395
private static bool DoesNodeHaveTag ( SyntaxNode xmlNode , string tagName , string ? attributeName = null , string ? attributeValue = null )
369
396
{
370
397
if ( xmlNode . Kind ( ) is SyntaxKind . XmlElement && xmlNode is XmlElementSyntax xmlElement )
0 commit comments