Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/nuget/Microsoft.Build-17.7.2
Browse files Browse the repository at this point in the history
  • Loading branch information
nenoNaninu authored Sep 10, 2023
2 parents 1832ff4 + 9b4e676 commit 8fd4359
Showing 1 changed file with 174 additions and 4 deletions.
178 changes: 174 additions & 4 deletions src/TypedSignalR.Client.TypeScript/InterfaceTranspiler.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.Logging;
using Tapper;
Expand Down Expand Up @@ -90,11 +92,14 @@ private static void AddInterface(
ITypedSignalRTranspilationOptions options,
ref CodeWriter codeWriter)
{

WriteJSDocInterfaceSummary(interfaceSymbol, ref codeWriter);

codeWriter.AppendLine($"export type {interfaceSymbol.Name} = {{");

foreach (var method in interfaceSymbol.GetMethods())
{
WriteJSDoc(method, ref codeWriter);
WriteJSDocMethod(method, ref codeWriter);
codeWriter.Append($" {method.Name.Format(options.MethodStyle)}(");
WriteParameters(method, options, specialSymbols, ref codeWriter);
codeWriter.Append("): ");
Expand All @@ -106,19 +111,142 @@ private static void AddInterface(
codeWriter.AppendLine();
}

private static void WriteJSDoc(IMethodSymbol methodSymbol, ref CodeWriter codeWriter)
private static void WriteJSDocInterfaceSummary(INamedTypeSymbol interfaceSymbol, ref CodeWriter codeWriter)
{
var documentationComment = GetDocumentationComment(interfaceSymbol);
var summaryList = documentationComment?.GetElementsByTagName("summary");

if (summaryList is null
|| summaryList.Count == 0
|| string.IsNullOrWhiteSpace(summaryList[0]!.InnerText))
{
return;
}

var summaryLines = summaryList[0]!.InnerText
.Trim()
.NormalizeNewLines(Environment.NewLine)
.Split(Environment.NewLine)
.Select(x => x.Trim());

codeWriter.AppendLine("/**");

foreach (var line in summaryLines)
{
codeWriter.AppendLine($"* {line}");
}

codeWriter.AppendLine($"*/");
}

private static void WriteJSDocMethod(IMethodSymbol methodSymbol, ref CodeWriter codeWriter)
{
var documentationComment = GetDocumentationComment(methodSymbol);

codeWriter.AppendLine(" /**");

if (documentationComment is not null)
{
WriteJSDocMethodSummary(documentationComment, ref codeWriter);
}

var parameterDocumentations = GetParameterDocumentationComments(documentationComment);

foreach (var parameter in methodSymbol.Parameters)
{
codeWriter.AppendLine($" * @param {parameter.Name} Transpiled from {parameter.Type.ToDisplayString()}");
WriteJSDocMethodParameter(parameter, parameterDocumentations, ref codeWriter);
}

codeWriter.AppendLine($" * @returns Transpiled from {methodSymbol.ReturnType.ToDisplayString()}");
WriteJSDocMethodReturn(methodSymbol, documentationComment, ref codeWriter);
codeWriter.AppendLine(" */");
}

private static void WriteJSDocMethodSummary(XmlDocument xmlDocument, ref CodeWriter codeWriter)
{
var summaryList = xmlDocument.GetElementsByTagName("summary");

if (summaryList.Count == 0
|| string.IsNullOrWhiteSpace(summaryList[0]?.InnerText))
{
return;
}

var summaryLines = summaryList[0]!.InnerText
.Trim()
.NormalizeNewLines(Environment.NewLine)
.Split(Environment.NewLine)
.Select(x => x.Trim());

foreach (var summary in summaryLines)
{
codeWriter.AppendLine($" * {summary}");
}
}

private static void WriteJSDocMethodParameter(IParameterSymbol parameter, IReadOnlyDictionary<string, string[]>? parameterDocumentations, ref CodeWriter codeWriter)
{
if (parameterDocumentations is null
|| !parameterDocumentations.TryGetValue(parameter.Name, out var parameterDocument)
|| parameterDocument.Length == 0
|| (parameterDocument.Length == 1 && string.IsNullOrWhiteSpace(parameterDocument[0])))
{
codeWriter.AppendLine($" * @param {parameter.Name} Transpiled from {parameter.Type.ToDisplayString()}");
return;
}

if (parameterDocument.Length == 1)
{
codeWriter.AppendLine($" * @param {parameter.Name} {parameterDocument[0]} (Transpiled from {parameter.Type.ToDisplayString()})");
return;
}

// if parameterDocument.Length > 1

codeWriter.AppendLine($" * @param {parameter.Name}");

foreach (var line in parameterDocument)
{
codeWriter.AppendLine($" * {line}");
}

codeWriter.AppendLine($" * (Transpiled from {parameter.Type.ToDisplayString()})");
}

private static void WriteJSDocMethodReturn(IMethodSymbol methodSymbol, XmlDocument? xmlDocument, ref CodeWriter codeWriter)
{
var returnList = xmlDocument?.GetElementsByTagName("returns");

if (returnList is null
|| returnList.Count == 0
|| string.IsNullOrWhiteSpace(returnList[0]?.InnerText))
{
codeWriter.AppendLine($" * @returns Transpiled from {methodSymbol.ReturnType.ToDisplayString()}");
return;
}

var returnSummaryLines = returnList[0]!.InnerText
.Trim()
.NormalizeNewLines(Environment.NewLine)
.Split(Environment.NewLine)
.Select(x => x.Trim())
.ToArray();

if (returnSummaryLines.Length == 1)
{
codeWriter.AppendLine($" * @returns {returnSummaryLines} (Transpiled from {methodSymbol.ReturnType.ToDisplayString()})");
return;
}

codeWriter.AppendLine($" * @returns");

foreach (var line in returnSummaryLines)
{
codeWriter.AppendLine($" * {line}");
}

codeWriter.AppendLine($" * (Transpiled from {methodSymbol.ReturnType.ToDisplayString()})");
}

private static void WriteParameters(IMethodSymbol methodSymbol, ITranspilationOptions options, SpecialSymbols specialSymbols, ref CodeWriter codeWriter)
{
if (methodSymbol.Parameters.Length == 0)
Expand Down Expand Up @@ -203,4 +331,46 @@ private static void WriteReturnType(

codeWriter.Append(TypeMapper.MapTo(returnType, options));
}

private static XmlDocument? GetDocumentationComment(ISymbol symbol)
{
var documentationComment = symbol.GetDocumentationCommentXml();

if (string.IsNullOrWhiteSpace(documentationComment))
{
return null;
}

try
{
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(documentationComment);
return xmlDocument;
}
catch
{
return null;
}
}

private static IReadOnlyDictionary<string, string[]>? GetParameterDocumentationComments(XmlDocument? xmlDocument)
{
if (xmlDocument is null)
{
return null;
}

return xmlDocument
.GetElementsByTagName("param")
.OfType<XmlElement>()
.ToDictionary(
x => x.GetAttribute("name"),
x => x.InnerText
.Trim()
.NormalizeNewLines(Environment.NewLine)
.Split(Environment.NewLine)
.Select(x => x.Trim())
.ToArray()
);
}
}

0 comments on commit 8fd4359

Please sign in to comment.