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 = XmlTagMapper.GetName(Tag); 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()); }
private void WriteDocumentationCommentToolTip(XElement element) { using (IEnumerator <XNode> en = element.Nodes().GetEnumerator()) { if (en.MoveNext()) { XNode node; var isFirst = true; bool isLast; do { node = en.Current; isLast = !en.MoveNext(); if (node is XText t) { string value = t.Value; value = TextUtility.RemoveLeadingTrailingNewLine(value, isFirst, isLast); Write(value); } else if (node is XElement e) { switch (XmlTagMapper.GetTagOrDefault(e.Name.LocalName)) { case XmlTag.C: { string value = e.Value; value = TextUtility.ToSingleLine(value); Write(value); break; } case XmlTag.Para: { WriteLine(); WriteLine(); WriteDocumentationCommentToolTip(e); WriteLine(); WriteLine(); break; } case XmlTag.ParamRef: { string parameterName = e.Attribute("name")?.Value; if (parameterName != null) { Write(parameterName); } break; } case XmlTag.See: { string commentId = e.Attribute("cref")?.Value; if (commentId != null) { ISymbol symbol = DocumentationProvider.GetFirstSymbolForDeclarationId(commentId); if (symbol != null) { Write(symbol.ToDisplayParts(Format.GetFormat())); } else { Write(TextUtility.RemovePrefixFromDocumentationCommentId(commentId)); } } break; } case XmlTag.TypeParamRef: { string typeParameterName = e.Attribute("name")?.Value; if (typeParameterName != null) { Write(typeParameterName); } break; } } } else { Debug.Fail(node.NodeType.ToString()); } isFirst = false; } while (!isLast); } } }
public override void WriteDocumentationComment(ISymbol symbol) { Debug.Assert(DocumentationDisplayMode == DocumentationDisplayMode.Xml, DocumentationDisplayMode.ToString()); IEnumerable <string> elementsText = DocumentationProvider?.GetXmlDocumentation(symbol)?.GetElementsAsText(skipEmptyElement: true, makeSingleLine: true); if (elementsText == null) { return; } foreach (string elementText in elementsText) { XElement element = XElement.Parse(elementText, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo); Dictionary <int, List <XElement> > elementsByLine = null; foreach (XElement e in element.Descendants()) { switch (XmlTagMapper.GetTagOrDefault(e.Name.LocalName)) { case XmlTag.See: case XmlTag.ParamRef: case XmlTag.TypeParamRef: { int lineNumber = ((IXmlLineInfo)e).LineNumber; if (elementsByLine == null) { elementsByLine = new Dictionary <int, List <XElement> >(); } if (elementsByLine.ContainsKey(lineNumber)) { elementsByLine[lineNumber].Add(e); } else { elementsByLine.Add(lineNumber, new List <XElement>() { e }); } break; } } } using (var sr = new StringReader(elementText)) { int lineNumber = 1; string line = null; while ((line = sr.ReadLine()) != null) { Write("/// "); if (elementsByLine != null && elementsByLine.TryGetValue(lineNumber, out List <XElement> elements)) { int lastPos = 0; foreach (XElement e in elements.OrderBy(e => ((IXmlLineInfo)e).LinePosition)) { int linePos = ((IXmlLineInfo)e).LinePosition - 2; switch (XmlTagMapper.GetTagOrDefault(e.Name.LocalName)) { case XmlTag.ParamRef: case XmlTag.TypeParamRef: { string name = e.Attribute("name")?.Value; if (name != null) { Write(line.Substring(lastPos, linePos - lastPos)); Write(name); } lastPos = linePos + e.ToString().Length; break; } case XmlTag.See: { string commentId = e.Attribute("cref")?.Value; if (commentId != null) { Write(line.Substring(lastPos, linePos - lastPos)); ISymbol s = DocumentationProvider.GetFirstSymbolForDeclarationId(commentId)?.OriginalDefinition; if (s != null) { if (s.Kind == SymbolKind.Field && s.ContainingType.TypeKind == TypeKind.Enum) { WriteSymbol(s.ContainingType); Write("."); Write(s.Name); } else { WriteParts(s, s.ToDisplayParts(TypeSymbolDisplayFormats.Name_ContainingTypes_Namespaces_GlobalNamespace_TypeParameters)); WriteSymbol(s); } } else { Debug.Fail(commentId); Write(TextUtility.RemovePrefixFromDocumentationCommentId(commentId)); } } else { string langword = e.Attribute("langword")?.Value; if (langword != null) { Write(line.Substring(lastPos, linePos - lastPos)); Write(langword); } } lastPos = linePos + e.ToString().Length; break; } } } WriteLine(line.Substring(lastPos)); } else { WriteLine(line); } WriteIndentation(); lineNumber++; } } } }
public static void WriteContentTo(this XElement element, DocumentationWriter writer, bool inlineOnly = false) { using (IEnumerator <XNode> en = element.Nodes().GetEnumerator()) { if (en.MoveNext()) { XNode node; var isFirst = true; bool isLast; do { node = en.Current; isLast = !en.MoveNext(); if (node is XText t) { string value = t.Value; value = TextUtility.RemoveLeadingTrailingNewLine(value, isFirst, isLast); if (inlineOnly) { value = TextUtility.ToSingleLine(value); } writer.WriteString(value); } else if (node is XElement e) { switch (XmlTagMapper.GetTagOrDefault(e.Name.LocalName)) { case XmlTag.C: { string value = e.Value; value = TextUtility.ToSingleLine(value); writer.WriteInlineCode(value); break; } case XmlTag.Code: { if (inlineOnly) { break; } string value = e.Value; value = TextUtility.RemoveLeadingTrailingNewLine(value); writer.WriteCodeBlock(value); break; } case XmlTag.List: { if (inlineOnly) { break; } string type = e.Attribute("type")?.Value; if (!string.IsNullOrEmpty(type)) { switch (type) { case "bullet": { WriteList(writer, e.Elements()); break; } case "number": { WriteList(writer, e.Elements(), isOrdered: true); break; } case "table": { WriteTable(writer, e.Elements()); break; } default: { Debug.Fail(type); break; } } } break; } case XmlTag.Para: { writer.WriteLine(); writer.WriteLine(); WriteContentTo(e, writer); writer.WriteLine(); writer.WriteLine(); break; } case XmlTag.ParamRef: { string parameterName = e.Attribute("name")?.Value; if (parameterName != null) { writer.WriteBold(parameterName); } break; } case XmlTag.See: { string commentId = e.Attribute("cref")?.Value; if (commentId != null) { ISymbol symbol = writer.DocumentationModel.GetFirstSymbolForDeclarationId(commentId); //XTODO: repair roslyn documentation Debug.Assert( symbol != null || commentId == "T:Microsoft.CodeAnalysis.CSharp.SyntaxNode" || commentId == "T:Microsoft.CodeAnalysis.CSharp.SyntaxToken" || commentId == "T:Microsoft.CodeAnalysis.CSharp.SyntaxTrivia" || commentId == "T:Microsoft.CodeAnalysis.VisualBasic.SyntaxNode" || commentId == "T:Microsoft.CodeAnalysis.VisualBasic.SyntaxToken" || commentId == "T:Microsoft.CodeAnalysis.VisualBasic.SyntaxTrivia", commentId); if (symbol != null) { writer.WriteLink(symbol, TypeSymbolDisplayFormats.Name_ContainingTypes_TypeParameters, SymbolDisplayAdditionalMemberOptions.UseItemPropertyName | SymbolDisplayAdditionalMemberOptions.UseOperatorName); } else { writer.WriteBold(TextUtility.RemovePrefixFromDocumentationCommentId(commentId)); } } break; } case XmlTag.TypeParamRef: { string typeParameterName = e.Attribute("name")?.Value; if (typeParameterName != null) { writer.WriteBold(typeParameterName); } break; } case XmlTag.Example: case XmlTag.Exception: case XmlTag.Exclude: case XmlTag.Include: case XmlTag.InheritDoc: case XmlTag.Param: case XmlTag.Permission: case XmlTag.Remarks: case XmlTag.Returns: case XmlTag.SeeAlso: case XmlTag.Summary: case XmlTag.TypeParam: case XmlTag.Value: { break; } default: { Debug.Fail(e.Name.LocalName); break; } } } else { Debug.Fail(node.NodeType.ToString()); } isFirst = false; } while (!isLast); } } }
internal bool HasTag(XmlTag tag) { return(XmlTagMapper.GetTagOrDefault(LocalName) == tag); }
internal XmlTag GetTag() { return(XmlTagMapper.GetTagOrDefault(LocalName)); }