/// <summary> /// Parses and constructs a <see cref="DocumentationComment" /> from the given fragment of XML. /// </summary> /// <param name="xml">The fragment of XML to parse.</param> /// <returns>A DocumentationComment instance.</returns> public static DocumentationComment FromXmlFragment(string xml) { var result = s_cacheLastXmlFragmentParse; if (result == null || result.FullXmlFragment != xml) { // Cache miss result = CommentBuilder.Parse(xml); s_cacheLastXmlFragmentParse = result; } return(result); }
/// <summary> /// Parses and constructs a <see cref="DocumentationComment" /> from the given fragment of XML. /// </summary> /// <param name="xml">The fragment of XML to parse.</param> /// <returns>A DocumentationComment instance.</returns> public static DocumentationComment FromXmlFragment(string xml) { var result = s_cacheLastXmlFragmentParse; if (result == null || result.FullXmlFragment != xml) { // Cache miss result = CommentBuilder.Parse(xml); s_cacheLastXmlFragmentParse = result; } return result; }
private CommentBuilder(string xml) { _comment = new DocumentationComment() { FullXmlFragment = xml }; }
private CommentBuilder(string xml) { _comment = new DocumentationComment(xml); }
public static DocumentationComment FromXmlFragment(string xml) { try { StringReader stringReader = new StringReader(xml); XmlReaderSettings settings = new XmlReaderSettings(); int num = 1; settings.ConformanceLevel = (ConformanceLevel)num; XmlReader xmlReader = XmlReader.Create((TextReader)stringReader, settings); DocumentationComment documentationComment = new DocumentationComment(); documentationComment.FullXmlFragment = xml; List <string> list1 = new List <string>(); List <string> list2 = new List <string>(); List <string> list3 = new List <string>(); try { Dictionary <string, List <string> > dictionary = new Dictionary <string, List <string> >(); while (!xmlReader.EOF) { if (xmlReader.IsStartElement()) { string localName = xmlReader.LocalName; if (DocumentationCommentXmlNames.ElementEquals(localName, "example", false) && documentationComment.ExampleText == null) { documentationComment.ExampleText = xmlReader.ReadInnerXml().Trim(); } else if (DocumentationCommentXmlNames.ElementEquals(localName, "summary", false) && documentationComment.SummaryText == null) { documentationComment.SummaryText = xmlReader.ReadInnerXml().Trim(); } else if (DocumentationCommentXmlNames.ElementEquals(localName, "returns", false) && documentationComment.ReturnsText == null) { documentationComment.ReturnsText = xmlReader.ReadInnerXml().Trim(); } else if (DocumentationCommentXmlNames.ElementEquals(localName, "remarks", false) && documentationComment.RemarksText == null) { documentationComment.RemarksText = xmlReader.ReadInnerXml().Trim(); } else if (DocumentationCommentXmlNames.ElementEquals(localName, "param", false)) { string attribute = xmlReader.GetAttribute("name"); string str = xmlReader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(attribute) && !documentationComment.parameterTexts.ContainsKey(attribute)) { list1.Add(attribute); documentationComment.parameterTexts.Add(attribute, str.Trim()); } } else if (DocumentationCommentXmlNames.ElementEquals(localName, "typeparam", false)) { string attribute = xmlReader.GetAttribute("name"); string str = xmlReader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(attribute) && !documentationComment.typeParameterTexts.ContainsKey(attribute)) { list2.Add(attribute); documentationComment.typeParameterTexts.Add(attribute, str.Trim()); } } else if (DocumentationCommentXmlNames.ElementEquals(localName, "exception", false)) { string attribute = xmlReader.GetAttribute("cref"); string str = xmlReader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(attribute)) { if (!dictionary.ContainsKey(attribute)) { list3.Add(attribute); dictionary.Add(attribute, new List <string>()); } dictionary[attribute].Add(str); } } else { xmlReader.Read(); } } else { xmlReader.Read(); } } foreach (KeyValuePair <string, List <string> > keyValuePair in dictionary) { documentationComment.exceptionTexts.Add(keyValuePair.Key, ImmutableArrayExtensions.AsImmutable <string>((IEnumerable <string>)keyValuePair.Value)); } } finally { documentationComment.ParameterNames = ImmutableArrayExtensions.AsImmutable <string>((IEnumerable <string>)list1); documentationComment.TypeParameterNames = ImmutableArrayExtensions.AsImmutable <string>((IEnumerable <string>)list2); documentationComment.ExceptionTypes = ImmutableArrayExtensions.AsImmutable <string>((IEnumerable <string>)list3); } return(documentationComment); } catch //(Exception ex) { DocumentationComment documentationComment = new DocumentationComment(); string str = xml; documentationComment.FullXmlFragment = str; int num = 1; documentationComment.HadXmlParseError = num != 0; return(documentationComment); } }
internal static ImmutableArray<string> Format(IDocumentationCommentFormattingService docCommentFormattingService, DocumentationComment docComment) { var formattedCommentLinesBuilder = ImmutableArray.CreateBuilder<string>(); var lineBuilder = new StringBuilder(); var formattedSummaryText = docCommentFormattingService.Format(docComment.SummaryText); if (!string.IsNullOrWhiteSpace(formattedSummaryText)) { formattedCommentLinesBuilder.Add(s_summaryHeader); formattedCommentLinesBuilder.AddRange(CreateWrappedTextFromRawText(formattedSummaryText)); } var parameterNames = docComment.ParameterNames; if (parameterNames.Length > 0) { formattedCommentLinesBuilder.Add(string.Empty); formattedCommentLinesBuilder.Add(s_paramHeader); for (int i = 0; i < parameterNames.Length; i++) { if (i != 0) { formattedCommentLinesBuilder.Add(string.Empty); } lineBuilder.Clear(); lineBuilder.Append(' ', s_indentSize); lineBuilder.Append(string.Format(s_labelFormat, parameterNames[i])); formattedCommentLinesBuilder.Add(lineBuilder.ToString()); var rawParameterText = docComment.GetParameterText(parameterNames[i]); var formattedParameterText = docCommentFormattingService.Format(rawParameterText); if (!string.IsNullOrWhiteSpace(formattedParameterText)) { formattedCommentLinesBuilder.AddRange(CreateWrappedTextFromRawText(formattedParameterText)); } } } var typeParameterNames = docComment.TypeParameterNames; if (typeParameterNames.Length > 0) { formattedCommentLinesBuilder.Add(string.Empty); formattedCommentLinesBuilder.Add(s_typeParameterHeader); for (int i = 0; i < typeParameterNames.Length; i++) { if (i != 0) { formattedCommentLinesBuilder.Add(string.Empty); } lineBuilder.Clear(); lineBuilder.Append(' ', s_indentSize); lineBuilder.Append(string.Format(s_labelFormat, typeParameterNames[i])); formattedCommentLinesBuilder.Add(lineBuilder.ToString()); var rawTypeParameterText = docComment.GetTypeParameterText(typeParameterNames[i]); var formattedTypeParameterText = docCommentFormattingService.Format(rawTypeParameterText); if (!string.IsNullOrWhiteSpace(formattedTypeParameterText)) { formattedCommentLinesBuilder.AddRange(CreateWrappedTextFromRawText(formattedTypeParameterText)); } } } var formattedReturnsText = docCommentFormattingService.Format(docComment.ReturnsText); if (!string.IsNullOrWhiteSpace(formattedReturnsText)) { formattedCommentLinesBuilder.Add(string.Empty); formattedCommentLinesBuilder.Add(s_returnsHeader); formattedCommentLinesBuilder.AddRange(CreateWrappedTextFromRawText(formattedReturnsText)); } var exceptionTypes = docComment.ExceptionTypes; if (exceptionTypes.Length > 0) { formattedCommentLinesBuilder.Add(string.Empty); formattedCommentLinesBuilder.Add(s_exceptionsHeader); for (int i = 0; i < exceptionTypes.Length; i++) { var rawExceptionTexts = docComment.GetExceptionTexts(exceptionTypes[i]); for (int j = 0; j < rawExceptionTexts.Length; j++) { if (i != 0 || j != 0) { formattedCommentLinesBuilder.Add(string.Empty); } lineBuilder.Clear(); lineBuilder.Append(' ', s_indentSize); lineBuilder.Append(string.Format(s_labelFormat, exceptionTypes[i])); formattedCommentLinesBuilder.Add(lineBuilder.ToString()); var formattedExceptionText = docCommentFormattingService.Format(rawExceptionTexts[j]); if (!string.IsNullOrWhiteSpace(formattedExceptionText)) { formattedCommentLinesBuilder.AddRange(CreateWrappedTextFromRawText(formattedExceptionText)); } } } } var formattedRemarksText = docCommentFormattingService.Format(docComment.RemarksText); if (!string.IsNullOrWhiteSpace(formattedRemarksText)) { formattedCommentLinesBuilder.Add(string.Empty); formattedCommentLinesBuilder.Add(s_remarksHeader); formattedCommentLinesBuilder.AddRange(CreateWrappedTextFromRawText(formattedRemarksText)); } // Eliminate any blank lines at the beginning. while (formattedCommentLinesBuilder.Count > 0 && formattedCommentLinesBuilder[0].Length == 0) { formattedCommentLinesBuilder.RemoveAt(0); } // Eliminate any blank lines at the end. while (formattedCommentLinesBuilder.Count > 0 && formattedCommentLinesBuilder[formattedCommentLinesBuilder.Count - 1].Length == 0) { formattedCommentLinesBuilder.RemoveAt(formattedCommentLinesBuilder.Count - 1); } return formattedCommentLinesBuilder.ToImmutable(); }
/// <summary> /// Parses and constructs a <see cref="DocumentationComment" /> from the given fragment of XML. /// </summary> /// <param name="xml">The fragment of XML to parse.</param> /// <returns>A DocumentationComment instance.</returns> public static DocumentationComment FromXmlFragment(string xml) { try { // TODO: probably want to preserve whitespace (DevDiv #13045). XmlReader reader = XmlReader.Create(new StringReader(xml), new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment }); DocumentationComment comment = new DocumentationComment(); comment.FullXmlFragment = xml; List<string> parameterNamesBuilder = new List<string>(); List<string> typeParameterNamesBuilder = new List<string>(); List<string> exceptionTypesBuilder = new List<string>(); try { Dictionary<string, List<string>> exceptionTextBuilders = new Dictionary<string, List<string>>(); while (!reader.EOF) { if (reader.IsStartElement()) { string localName = reader.LocalName; if (XmlNames.ElementEquals(localName, XmlNames.ExampleElementName) && comment.ExampleText == null) { comment.ExampleText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.SummaryElementName) && comment.SummaryText == null) { comment.SummaryText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.ReturnsElementName) && comment.ReturnsText == null) { comment.ReturnsText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.RemarksElementName) && comment.RemarksText == null) { comment.RemarksText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.ParameterElementName)) { string name = reader.GetAttribute(XmlNames.NameAttributeName); string paramText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(name) && !comment.parameterTexts.ContainsKey(name)) { parameterNamesBuilder.Add(name); comment.parameterTexts.Add(name, paramText.Trim()); // TODO: trim each line } } else if (XmlNames.ElementEquals(localName, XmlNames.TypeParameterElementName)) { string name = reader.GetAttribute(XmlNames.NameAttributeName); string typeParamText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(name) && !comment.typeParameterTexts.ContainsKey(name)) { typeParameterNamesBuilder.Add(name); comment.typeParameterTexts.Add(name, typeParamText.Trim()); // TODO: trim each line } } else if (XmlNames.ElementEquals(localName, XmlNames.ExceptionElementName)) { string type = reader.GetAttribute(XmlNames.CrefAttributeName); string exceptionText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(type)) { if (!exceptionTextBuilders.ContainsKey(type)) { exceptionTypesBuilder.Add(type); exceptionTextBuilders.Add(type, new List<string>()); } exceptionTextBuilders[type].Add(exceptionText); } } else if (XmlNames.ElementEquals(localName, XmlNames.CompletionListElementName)) { string cref = reader.GetAttribute(XmlNames.CrefAttributeName); if (!string.IsNullOrWhiteSpace(cref)) { comment.CompletionListCref = cref; } reader.ReadInnerXml(); } else { // This is an element we don't handle. Skip it. reader.Read(); } } else { // We came across something that isn't a start element, like a block of text. // Skip it. reader.Read(); } } foreach (var typeAndBuilderPair in exceptionTextBuilders) { comment.exceptionTexts.Add(typeAndBuilderPair.Key, typeAndBuilderPair.Value.AsImmutable()); } } finally { comment.ParameterNames = parameterNamesBuilder.AsImmutable(); comment.TypeParameterNames = typeParameterNamesBuilder.AsImmutable(); comment.ExceptionTypes = exceptionTypesBuilder.AsImmutable(); } return comment; } catch (Exception) { // It would be nice if we only had to catch XmlException to handle invalid XML // while parsing doc comments. Unfortunately, other exceptions can also occur, // so we just catch them all. See Dev12 Bug 612456 for an example. return new DocumentationComment { FullXmlFragment = xml, HadXmlParseError = true }; } }
/// <summary> /// Parses and constructs a <see cref="DocumentationComment" /> from the given fragment of XML. /// </summary> /// <param name="xml">The fragment of XML to parse.</param> /// <returns>A DocumentationComment instance.</returns> public static DocumentationComment FromXmlFragment(string xml) { try { // TODO: probably want to preserve whitespace (DevDiv #13045). XmlReader reader = XmlReader.Create(new StringReader(xml), new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment }); DocumentationComment comment = new DocumentationComment(); comment.FullXmlFragment = xml; List <string> parameterNamesBuilder = new List <string>(); List <string> typeParameterNamesBuilder = new List <string>(); List <string> exceptionTypesBuilder = new List <string>(); try { Dictionary <string, List <string> > exceptionTextBuilders = new Dictionary <string, List <string> >(); while (!reader.EOF) { if (reader.IsStartElement()) { string localName = reader.LocalName; if (XmlNames.ElementEquals(localName, XmlNames.ExampleElementName) && comment.ExampleText == null) { comment.ExampleText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.SummaryElementName) && comment.SummaryText == null) { comment.SummaryText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.ReturnsElementName) && comment.ReturnsText == null) { comment.ReturnsText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.RemarksElementName) && comment.RemarksText == null) { comment.RemarksText = reader.ReadInnerXml().Trim(); // TODO: trim each line } else if (XmlNames.ElementEquals(localName, XmlNames.ParameterElementName)) { string name = reader.GetAttribute(XmlNames.NameAttributeName); string paramText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(name) && !comment.parameterTexts.ContainsKey(name)) { parameterNamesBuilder.Add(name); comment.parameterTexts.Add(name, paramText.Trim()); // TODO: trim each line } } else if (XmlNames.ElementEquals(localName, XmlNames.TypeParameterElementName)) { string name = reader.GetAttribute(XmlNames.NameAttributeName); string typeParamText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(name) && !comment.typeParameterTexts.ContainsKey(name)) { typeParameterNamesBuilder.Add(name); comment.typeParameterTexts.Add(name, typeParamText.Trim()); // TODO: trim each line } } else if (XmlNames.ElementEquals(localName, XmlNames.ExceptionElementName)) { string type = reader.GetAttribute(XmlNames.CrefAttributeName); string exceptionText = reader.ReadInnerXml(); if (!string.IsNullOrWhiteSpace(type)) { if (!exceptionTextBuilders.ContainsKey(type)) { exceptionTypesBuilder.Add(type); exceptionTextBuilders.Add(type, new List <string>()); } exceptionTextBuilders[type].Add(exceptionText); } } else if (XmlNames.ElementEquals(localName, XmlNames.CompletionListElementName)) { string cref = reader.GetAttribute(XmlNames.CrefAttributeName); if (!string.IsNullOrWhiteSpace(cref)) { comment.CompletionListCref = cref; } reader.ReadInnerXml(); } else { // This is an element we don't handle. Skip it. reader.Read(); } } else { // We came across something that isn't a start element, like a block of text. // Skip it. reader.Read(); } } foreach (var typeAndBuilderPair in exceptionTextBuilders) { comment.exceptionTexts.Add(typeAndBuilderPair.Key, typeAndBuilderPair.Value.AsImmutable()); } } finally { comment.ParameterNames = parameterNamesBuilder.AsImmutable(); comment.TypeParameterNames = typeParameterNamesBuilder.AsImmutable(); comment.ExceptionTypes = exceptionTypesBuilder.AsImmutable(); } return(comment); } catch (Exception) { // It would be nice if we only had to catch XmlException to handle invalid XML // while parsing doc comments. Unfortunately, other exceptions can also occur, // so we just catch them all. See Dev12 Bug 612456 for an example. return(new DocumentationComment { FullXmlFragment = xml, HadXmlParseError = true }); } }