Skip to content

Commit

Permalink
Merge pull request #1038 from akshita31/typelookup_v2
Browse files Browse the repository at this point in the history
TypeLookUp Structured Documentation Feature to be used by VS Code
  • Loading branch information
DustinCampbell authored Dec 8, 2017
2 parents eae75dc + 5494fb9 commit aadc234
Show file tree
Hide file tree
Showing 5 changed files with 559 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;

namespace OmniSharp.Models.TypeLookup
{
public class DocumentationComment
{
public string SummaryText { get; }
public string[] TypeParamElements { get; }
public string[] ParamElements { get; }
public string ReturnsText { get; }
public string RemarksText { get; }
public string ExampleText { get; }
public string ValueText { get; }
public string[ ] Exception { get; }

private DocumentationComment(string summaryText, string[] typeParamElements, string[] paramElements, string returnsText, string remarksText, string exampleText, string valueText, string [ ] exception)
{
SummaryText = summaryText;
TypeParamElements = typeParamElements;
ParamElements = paramElements;
ReturnsText = returnsText;
RemarksText = remarksText;
ExampleText = exampleText;
ValueText = valueText;
Exception = exception;
}

public static DocumentationComment From(string xmlDocumentation, string lineEnding)
{
var reader = new StringReader("<docroot>" + xmlDocumentation + "</docroot>");
StringBuilder summaryText = new StringBuilder();
List<StringBuilder> typeParamElements = new List<StringBuilder>();
List<StringBuilder> paramElements = new List<StringBuilder>();
StringBuilder returnsText = new StringBuilder();
StringBuilder remarksText = new StringBuilder();
StringBuilder exampleText = new StringBuilder();
StringBuilder valueText = new StringBuilder();
List<StringBuilder> exception = new List<StringBuilder>();

using (var xml = XmlReader.Create(reader))
{
try
{
xml.Read();
string elementName = null;
StringBuilder currentSectionBuilder = null;
do
{
if (xml.NodeType == XmlNodeType.Element)
{
elementName = xml.Name.ToLowerInvariant();
switch (elementName)
{
case "filterpriority":
xml.Skip();
break;
case "remarks":
remarksText.Append("Remarks: ");
currentSectionBuilder = remarksText;
break;
case "example":
exampleText.Append("Example: ");
currentSectionBuilder = exampleText;
break;
case "exception":
StringBuilder ExceptionInstance = new StringBuilder();
ExceptionInstance.Append(GetCref(xml["cref"]).TrimEnd());
ExceptionInstance.Append(": ");
currentSectionBuilder = ExceptionInstance;
exception.Add(ExceptionInstance);
break;
case "returns":
returnsText.Append("Returns: ");
currentSectionBuilder = returnsText;
break;
case "summary":
summaryText.Append("Summary: ");
currentSectionBuilder = summaryText;
break;
case "see":
currentSectionBuilder.Append(GetCref(xml["cref"]));
currentSectionBuilder.Append(xml["langword"]);
break;
case "seealso":
currentSectionBuilder.Append("See also: ");
currentSectionBuilder.Append(GetCref(xml["cref"]));
break;
case "paramref":
currentSectionBuilder.Append(xml["name"]);
currentSectionBuilder.Append(" ");
break;
case "param":
StringBuilder paramInstance = new StringBuilder();
paramInstance.Append(TrimMultiLineString(xml["name"], lineEnding));
paramInstance.Append(": ");
currentSectionBuilder = paramInstance;
paramElements.Add(paramInstance);
break;
case "typeparamref":
currentSectionBuilder.Append(xml["name"]);
currentSectionBuilder.Append(" ");
break;
case "typeparam":
StringBuilder typeParamInstance = new StringBuilder();
typeParamInstance.Append(TrimMultiLineString(xml["name"], lineEnding));
typeParamInstance.Append(": ");
currentSectionBuilder = typeParamInstance;
typeParamElements.Add(typeParamInstance);
break;
case "value":
valueText.Append("Value: ");
currentSectionBuilder = valueText;
break;
case "br":
case "para":
currentSectionBuilder.Append(lineEnding);
break;
}
}
else if (xml.NodeType == XmlNodeType.Text && currentSectionBuilder != null)
{
if (elementName == "code")
{
currentSectionBuilder.Append(xml.Value);
}
else
{
currentSectionBuilder.Append(TrimMultiLineString(xml.Value, lineEnding));
}
}
} while (xml.Read());
}
catch (Exception)
{
return null;
}
}
return new DocumentationComment(summaryText.ToString(), typeParamElements.Select(s => s.ToString()).ToArray(), paramElements.Select(s => s.ToString()).ToArray(), returnsText.ToString(), remarksText.ToString(), exampleText.ToString(), valueText.ToString(), exception.Select(s => s.ToString()).ToArray());
}

private static string TrimMultiLineString(string input, string lineEnding)
{
var lines = input.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
return string.Join(lineEnding, lines.Select(l => l.TrimStart()));
}

private static string GetCref(string cref)
{
if (cref == null || cref.Trim().Length == 0)
{
return "";
}
if (cref.Length < 2)
{
return cref;
}
if (cref.Substring(1, 1) == ":")
{
return cref.Substring(2, cref.Length - 2) + " ";
}
return cref + " ";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ public class TypeLookupResponse
{
public string Type { get; set; }
public string Documentation { get; set; }
public DocumentationComment StructuredDocumentation { get; set; }
}
}
}
10 changes: 10 additions & 0 deletions src/OmniSharp.Roslyn.CSharp/Services/DocumentationConverter.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using OmniSharp.Models.TypeLookup;

namespace OmniSharp.Roslyn.CSharp.Services.Documentation
{
Expand Down Expand Up @@ -126,5 +128,13 @@ private static string GetCref(string cref)
}
return cref + " ";
}

public static DocumentationComment GetStructuredDocumentation(string xmlDocumentation, string lineEnding)
{
if (string.IsNullOrEmpty(xmlDocumentation))
return null;
return DocumentationComment.From(xmlDocumentation, lineEnding);
}
}
}

1 change: 1 addition & 0 deletions src/OmniSharp.Roslyn.CSharp/Services/Types/TypeLookup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public async Task<TypeLookupResponse> Handle(TypeLookupRequest request)
if (request.IncludeDocumentation)
{
response.Documentation = DocumentationConverter.ConvertDocumentation(symbol.GetDocumentationCommentXml(), _formattingOptions.NewLine);
response.StructuredDocumentation = DocumentationConverter.GetStructuredDocumentation(symbol.GetDocumentationCommentXml(), _formattingOptions.NewLine);
}
}
}
Expand Down
Loading

0 comments on commit aadc234

Please sign in to comment.