-
Notifications
You must be signed in to change notification settings - Fork 4.1k
/
DocCommentConverter.cs
100 lines (81 loc) · 3.76 KB
/
DocCommentConverter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.DocumentationComments;
using Microsoft.CodeAnalysis.MetadataAsSource;
using Microsoft.CodeAnalysis.Shared.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.DocumentationComments
{
internal class DocCommentConverter : CSharpSyntaxRewriter
{
private readonly IDocumentationCommentFormattingService _formattingService;
private readonly CancellationToken _cancellationToken;
public static SyntaxNode ConvertToRegularComments(SyntaxNode node, IDocumentationCommentFormattingService formattingService, CancellationToken cancellationToken)
{
var converter = new DocCommentConverter(formattingService, cancellationToken);
return converter.Visit(node);
}
private DocCommentConverter(IDocumentationCommentFormattingService formattingService, CancellationToken cancellationToken)
: base(visitIntoStructuredTrivia: false)
{
_formattingService = formattingService;
_cancellationToken = cancellationToken;
}
public override SyntaxNode Visit(SyntaxNode node)
{
_cancellationToken.ThrowIfCancellationRequested();
if (node == null)
{
return node;
}
// Process children first
node = base.Visit(node);
// Check the leading trivia for doc comments.
if (node.GetLeadingTrivia().Any(SyntaxKind.SingleLineDocumentationCommentTrivia))
{
var newLeadingTrivia = new List<SyntaxTrivia>();
foreach (var trivia in node.GetLeadingTrivia())
{
if (trivia.Kind() == SyntaxKind.SingleLineDocumentationCommentTrivia)
{
var structuredTrivia = (DocumentationCommentTriviaSyntax)trivia.GetStructure();
var commentLines = ConvertDocCommentToRegularComment(structuredTrivia).ToSyntaxTriviaList();
if (commentLines.Count > 0)
{
newLeadingTrivia.Add(SyntaxFactory.Comment("//"));
newLeadingTrivia.Add(SyntaxFactory.ElasticCarriageReturnLineFeed);
newLeadingTrivia.AddRange(commentLines);
}
}
else
{
newLeadingTrivia.Add(trivia);
}
}
node = node.WithLeadingTrivia(newLeadingTrivia);
}
return node;
}
private IEnumerable<SyntaxTrivia> ConvertDocCommentToRegularComment(DocumentationCommentTriviaSyntax structuredTrivia)
{
var xmlFragment = DocumentationCommentUtilities.ExtractXMLFragment(structuredTrivia.ToFullString(), "///");
var docComment = DocumentationComment.FromXmlFragment(xmlFragment);
var commentLines = AbstractMetadataAsSourceService.DocCommentFormatter.Format(_formattingService, docComment);
foreach (var line in commentLines)
{
if (!string.IsNullOrWhiteSpace(line))
{
yield return SyntaxFactory.Comment("// " + line);
}
else
{
yield return SyntaxFactory.Comment("//");
}
yield return SyntaxFactory.ElasticCarriageReturnLineFeed;
}
}
}
}