| File: DocumentationComments\DocCommentConverter.cs | Web Access |
| Project: src\roslyn\src\Features\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.Features.csproj (Microsoft.CodeAnalysis.CSharp.Features) |
// 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. #nullable disable 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 sealed 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; } } }