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); } }
public static bool IsMultilineDocComment(this DocumentationCommentTriviaSyntax documentationComment) { if (documentationComment == null) { return(false); } return(documentationComment.ToFullString().StartsWith("/**", StringComparison.Ordinal)); }
private string GetNewTrivia( DocumentationCommentTriviaSyntax comment, List <ElementInfo <TNode> > elementInfos) { var sb = new StringBuilder(); string text = comment.ToFullString(); int start = comment.FullSpan.Start; int startIndex = 0; string elementName = XmlElementNameKindMapper.GetName(ElementKind); foreach (IGrouping <int, ElementInfo <TNode> > grouping in elementInfos .OrderBy(f => f.InsertIndex) .GroupBy(f => f.InsertIndex)) { int endIndex = grouping.Key - start; sb.Append(text, startIndex, endIndex - startIndex); foreach (ElementInfo <TNode> elementInfo in grouping) { if (elementInfo.NewLinePosition == NewLinePosition.Beginning) { sb.AppendLine(); } sb.Append("/// <") .Append(elementName) .Append(" name=\"") .Append(elementInfo.Name) .Append("\"></") .Append(elementName) .Append(">"); if (elementInfo.NewLinePosition == NewLinePosition.End) { sb.AppendLine(); } } startIndex = endIndex; } sb.Append(text, startIndex, text.Length - startIndex); return(sb.ToString()); }
public string GetNewTrivia( DocumentationCommentTriviaSyntax comment, List <ElementInfo <TNode> > elementInfos) { var sb = new StringBuilder(); string text = comment.ToFullString(); int start = comment.FullSpan.Start; int startIndex = 0; foreach (IGrouping <int, ElementInfo <TNode> > grouping in elementInfos .OrderBy(f => f.InsertIndex) .GroupBy(f => f.InsertIndex)) { int endIndex = grouping.Key - start; sb.Append(text.Substring(startIndex, endIndex - startIndex)); foreach (ElementInfo <TNode> elementInfo in grouping) { if (elementInfo.NewLinePosition == NewLinePosition.Beginning) { sb.AppendLine(); } sb.Append($"/// <{ElementName} name=\"{elementInfo.Name}\"></{ElementName}>"); if (elementInfo.NewLinePosition == NewLinePosition.End) { sb.AppendLine(); } } startIndex = endIndex; } sb.Append(text.Substring(startIndex)); return(sb.ToString()); }
private async Task <Document> CreateChangedDocumentAsync(CodeFixContext context, DocumentationCommentTriviaSyntax documentationCommentTriviaSyntax, CancellationToken cancellationToken) { StringBuilder leadingTriviaBuilder = new StringBuilder(); SyntaxToken parentToken = documentationCommentTriviaSyntax.ParentTrivia.Token; int documentationCommentIndex = parentToken.LeadingTrivia.IndexOf(documentationCommentTriviaSyntax.ParentTrivia); for (int i = 0; i < documentationCommentIndex; i++) { SyntaxTrivia trivia = parentToken.LeadingTrivia[i]; switch (trivia.Kind()) { case SyntaxKind.EndOfLineTrivia: leadingTriviaBuilder.Clear(); break; case SyntaxKind.WhitespaceTrivia: leadingTriviaBuilder.Append(trivia.ToFullString()); break; default: break; } } leadingTriviaBuilder.Append(documentationCommentTriviaSyntax.GetLeadingTrivia().ToFullString()); // this is the trivia that should appear at the beginning of each line of the comment. SyntaxTrivia leadingTrivia = SyntaxFactory.DocumentationCommentExterior(leadingTriviaBuilder.ToString()); string newLineText = context.Document.Project.Solution.Workspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp); var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken); var documentedSymbol = semanticModel.GetDeclaredSymbol(parentToken.Parent.FirstAncestorOrSelf <SyntaxNode>(SyntaxNodeExtensionsEx.IsSymbolDeclaration), context.CancellationToken); DocumentationCommentTriviaSyntax contentsOnly = RemoveExteriorTrivia(documentationCommentTriviaSyntax); contentsOnly = contentsOnly.ReplaceNodes(contentsOnly.ChildNodes(), (originalNode, rewrittenNode) => RenderBlockElementAsMarkdown(originalNode, rewrittenNode, newLineText, documentedSymbol)); string renderedContent = contentsOnly.Content.ToFullString(); string[] lines = renderedContent.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); SyntaxList <XmlNodeSyntax> newContent = XmlSyntaxFactory.List(); for (int i = 0; i < lines.Length; i++) { string line = lines[i]; if (string.IsNullOrWhiteSpace(line)) { if (i == lines.Length - 1) { break; } line = string.Empty; } if (newContent.Count > 0) { newContent = newContent.Add(XmlSyntaxFactory.NewLine(newLineText).WithTrailingTrivia(SyntaxFactory.DocumentationCommentExterior("///"))); } newContent = newContent.Add(XmlSyntaxFactory.Text(line.TrimEnd(), xmlEscape: false)); } contentsOnly = contentsOnly.WithContent(newContent); contentsOnly = contentsOnly .ReplaceExteriorTrivia(leadingTrivia) .WithLeadingTrivia(SyntaxFactory.DocumentationCommentExterior("///")) .WithTrailingTrivia(SyntaxFactory.EndOfLine(Environment.NewLine)); string fullContent = contentsOnly.ToFullString(); SyntaxTriviaList parsedTrivia = SyntaxFactory.ParseLeadingTrivia(fullContent); SyntaxTrivia documentationTrivia = parsedTrivia.FirstOrDefault(i => i.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia)); contentsOnly = documentationTrivia.GetStructure() as DocumentationCommentTriviaSyntax; if (contentsOnly == null) { return(context.Document); } // Remove unnecessary nested paragraph elements contentsOnly = contentsOnly.ReplaceNodes(contentsOnly.DescendantNodes().OfType <XmlElementSyntax>(), MarkUnnecessaryParagraphs); contentsOnly = contentsOnly.ReplaceNodes(contentsOnly.DescendantNodes().OfType <XmlElementSyntax>(), RemoveUnnecessaryParagraphs); SyntaxNode root = await context.Document.GetSyntaxRootAsync(cancellationToken); SyntaxNode newRoot = root.ReplaceNode(documentationCommentTriviaSyntax, contentsOnly); if (documentationCommentTriviaSyntax.IsEquivalentTo(contentsOnly)) { return(context.Document); } if (documentationCommentTriviaSyntax.ToFullString().Equals(contentsOnly.ToFullString(), StringComparison.Ordinal)) { return(context.Document); } return(context.Document.WithSyntaxRoot(newRoot)); }
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; } }
public static bool IsMultilineDocComment(this DocumentationCommentTriviaSyntax documentationComment) { return(documentationComment.ToFullString().StartsWith("/**")); }
string WriteMethod(ClassBuilder cb, MethodDeclarationSyntax method, DocumentationCommentTriviaSyntax comment, bool useRemotes) { int remoteCount = 0; StringBuilder sb = new StringBuilder(); if (comment != null) { string formattedComment = T2 + comment.ToFullString().Replace(T1, T2); foreach (var line in formattedComment.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None)) { if (!line.Contains("<since>") && !string.IsNullOrWhiteSpace(line)) { sb.AppendLine(line); } } } bool useAsReturnType; if (method.IsNonConst(out useAsReturnType) && useAsReturnType) { sb.Append($"{T2}public static {cb.ClassName} {method.Identifier}("); } else { sb.Append($"{T2}public static {method.ReturnType} {method.Identifier}("); } int paramCount = 0; if (!method.IsStatic()) { if (useRemotes && IsRemoteCandidate(cb.ClassName)) { sb.Append($"Remote<{cb.ClassName}> {cb.ClassName.ToLower()}"); remoteCount++; } else { sb.Append($"this {cb.ClassName} {cb.ClassName.ToLower()}"); } paramCount++; } if (method.IsNonConst(out useAsReturnType) && !useAsReturnType) { if (paramCount > 0) { sb.Append(", "); } sb.Append($"out {cb.ClassName} updatedInstance"); paramCount++; } for (int i = 0; i < method.ParameterList.Parameters.Count; i++) { if (paramCount > 0) { sb.Append(", "); } var parameter = method.ParameterList.Parameters[i]; if (useRemotes && IsRemoteCandidate(parameter.Type.ToString())) { sb.Append($"Remote<{parameter.Type}> {parameter.Identifier}"); remoteCount++; } else { sb.Append($"{parameter.ToFullString().Trim()}"); } paramCount++; } sb.AppendLine(")"); sb.AppendLine($"{T2}{{"); List <int> outParamIndices = new List <int>(); for (int i = 0; i < method.ParameterList.Parameters.Count; i++) { foreach (var modifier in method.ParameterList.Parameters[i].Modifiers) { if (modifier.Text == "out") { outParamIndices.Add(i); } } } if (outParamIndices.Count == 0) { if (method.IsNonConst(out useAsReturnType)) { if (useAsReturnType) { sb.Append($"{T3}return ComputeServer.Post<{cb.ClassName}>(ApiAddress(), "); } else { sb.Append($"{T3}return ComputeServer.Post<{method.ReturnType}, {cb.ClassName}>(ApiAddress(), out updatedInstance, "); } } else { sb.Append($"{T3}return ComputeServer.Post<{method.ReturnType}>(ApiAddress(), "); } } else { var parameter0 = method.ParameterList.Parameters[outParamIndices[0]]; if (outParamIndices.Count == 1) { sb.Append($"{T3}return ComputeServer.Post<{method.ReturnType}, {parameter0.Type}>(ApiAddress(), out {parameter0.Identifier}, "); } else { var parameter1 = method.ParameterList.Parameters[outParamIndices[1]]; sb.Append($"{T3}return ComputeServer.Post<{method.ReturnType}, {parameter0.Type}, {parameter1.Type}>(ApiAddress(), out {parameter0.Identifier}, out {parameter1.Identifier}, "); } } if (!method.IsStatic()) { sb.Append($"{cb.ClassName.ToLower()}"); if (method.ParameterList.Parameters.Count > 0) { sb.Append(", "); } } var orderedParams = new List <ParameterSyntax>(); foreach (var p in method.ParameterList.Parameters) { if (p.Modifiers.Count == 0) { orderedParams.Add(p); } } for (int i = 0; i < orderedParams.Count; i++) { if (i > 0) { sb.Append(", "); } var p = orderedParams[i]; sb.Append(p.Modifiers.Count > 0 ? $"{p.Modifiers} {p.Identifier}" : $"{p.Identifier}"); } sb.AppendLine(");"); sb.AppendLine($"{T2}}}"); if (remoteCount == 0 && useRemotes) { return(""); } return(sb.ToString()); }