diff --git a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs index 8643fc8..2bbd253 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs @@ -227,6 +227,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); } @@ -1943,4 +1946,247 @@ public DoSomething(): void { """); } + + [Test] + public void TypeScriptUserClassProxy_ConstructorWithSummaryComment_RendersJSDoc() + { + SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(""" + using System; + namespace N1; + [TSExport] + public class C1 + { + /// + /// Initializes a new instance with bold formatting. + /// + public C1(string name) {} + public string Name => name; + } + """); + + SymbolExtractor symbolExtractor = new([CSharpFileInfo.Create(syntaxTree)], TestFixture.TargetingPackRefDir); + List exportedClasses = [.. symbolExtractor.ExtractAllExportedSymbols()]; + Assert.That(exportedClasses, Has.Count.EqualTo(1)); + INamedTypeSymbol classSymbol = exportedClasses[0]; + + InteropTypeInfoCache typeCache = new(); + ClassInfo classInfo = new ClassInfoBuilder(classSymbol, typeCache).Build(); + + RenderContext renderContext = new(classInfo, [classInfo], RenderOptions.TypeScript); + new TypescriptUserClassProxyRenderer(renderContext).Render(); + + AssertEx.EqualOrDiff(renderContext.ToString(), """ +export class C1 extends ProxyBase { + /** + * Initializes a new instance with **bold** formatting. + */ + constructor(name: string) { + super(TypeShimConfig.exports.N1.C1Interop.ctor(name)); + } + + public get Name(): string { + return TypeShimConfig.exports.N1.C1Interop.get_Name(this.instance); + } +} + +"""); + } + + [Test] + public void TypeScriptUserClassProxy_ConstructorWithParams_RendersJSDoc() + { + SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(""" + using System; + namespace N1; + [TSExport] + public class C1 + { + /// + /// Initializes a new instance. + /// + /// The name of the instance + /// The initial value + public C1(string name, int value) {} + public string Name => name; + } + """); + + SymbolExtractor symbolExtractor = new([CSharpFileInfo.Create(syntaxTree)], TestFixture.TargetingPackRefDir); + List exportedClasses = [.. symbolExtractor.ExtractAllExportedSymbols()]; + Assert.That(exportedClasses, Has.Count.EqualTo(1)); + INamedTypeSymbol classSymbol = exportedClasses[0]; + + InteropTypeInfoCache typeCache = new(); + ClassInfo classInfo = new ClassInfoBuilder(classSymbol, typeCache).Build(); + + RenderContext renderContext = new(classInfo, [classInfo], RenderOptions.TypeScript); + new TypescriptUserClassProxyRenderer(renderContext).Render(); + + AssertEx.EqualOrDiff(renderContext.ToString(), """ +export class C1 extends ProxyBase { + /** + * Initializes a new instance. + * @param name - The name of the instance + * @param value - The initial value + */ + constructor(name: string, value: number) { + super(TypeShimConfig.exports.N1.C1Interop.ctor(name, value)); + } + + public get Name(): string { + return TypeShimConfig.exports.N1.C1Interop.get_Name(this.instance); + } +} + +"""); + } + + [Test] + public void TypeScriptUserClassProxy_ConstructorWithRemarks_RendersJSDoc() + { + SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(""" + using System; + namespace N1; + [TSExport] + public class C1 + { + /// + /// Initializes a new instance. + /// + /// + /// Use this constructor when you need a named instance. + /// + public C1(string name) {} + public string Name => name; + } + """); + + SymbolExtractor symbolExtractor = new([CSharpFileInfo.Create(syntaxTree)], TestFixture.TargetingPackRefDir); + List exportedClasses = [.. symbolExtractor.ExtractAllExportedSymbols()]; + Assert.That(exportedClasses, Has.Count.EqualTo(1)); + INamedTypeSymbol classSymbol = exportedClasses[0]; + + InteropTypeInfoCache typeCache = new(); + ClassInfo classInfo = new ClassInfoBuilder(classSymbol, typeCache).Build(); + + RenderContext renderContext = new(classInfo, [classInfo], RenderOptions.TypeScript); + new TypescriptUserClassProxyRenderer(renderContext).Render(); + + AssertEx.EqualOrDiff(renderContext.ToString(), """ +export class C1 extends ProxyBase { + /** + * Initializes a new instance. + * @remarks + * Use this constructor when you need a named instance. + */ + constructor(name: string) { + super(TypeShimConfig.exports.N1.C1Interop.ctor(name)); + } + + public get Name(): string { + return TypeShimConfig.exports.N1.C1Interop.get_Name(this.instance); + } +} + +"""); + } + + [Test] + public void TypeScriptUserClassProxy_ConstructorWithException_RendersJSDoc() + { + SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(""" + using System; + namespace N1; + [TSExport] + public class C1 + { + /// + /// Initializes a new instance. + /// + /// The name of the instance + /// Thrown when name is null + public C1(string name) {} + public string Name => name; + } + """); + + SymbolExtractor symbolExtractor = new([CSharpFileInfo.Create(syntaxTree)], TestFixture.TargetingPackRefDir); + List exportedClasses = [.. symbolExtractor.ExtractAllExportedSymbols()]; + Assert.That(exportedClasses, Has.Count.EqualTo(1)); + INamedTypeSymbol classSymbol = exportedClasses[0]; + + InteropTypeInfoCache typeCache = new(); + ClassInfo classInfo = new ClassInfoBuilder(classSymbol, typeCache).Build(); + + RenderContext renderContext = new(classInfo, [classInfo], RenderOptions.TypeScript); + new TypescriptUserClassProxyRenderer(renderContext).Render(); + + AssertEx.EqualOrDiff(renderContext.ToString(), """ +export class C1 extends ProxyBase { + /** + * Initializes a new instance. + * @param name - The name of the instance + * @throws {System.ArgumentNullException} Thrown when name is null + */ + constructor(name: string) { + super(TypeShimConfig.exports.N1.C1Interop.ctor(name)); + } + + public get Name(): string { + return TypeShimConfig.exports.N1.C1Interop.get_Name(this.instance); + } +} + +"""); + } + + [Test] + public void TypeScriptUserClassProxy_ConstructorWithCommentAndSettableProperty_RendersJSDocWithInsertedInitializerParam() + { + SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(""" + using System; + namespace N1; + [TSExport] + public class C1 + { + /// + /// Initializes a new instance. + /// + public C1() {} + public string Name { get; set; } + } + """); + + SymbolExtractor symbolExtractor = new([CSharpFileInfo.Create(syntaxTree)], TestFixture.TargetingPackRefDir); + List exportedClasses = [.. symbolExtractor.ExtractAllExportedSymbols()]; + Assert.That(exportedClasses, Has.Count.EqualTo(1)); + INamedTypeSymbol classSymbol = exportedClasses[0]; + + InteropTypeInfoCache typeCache = new(); + ClassInfo classInfo = new ClassInfoBuilder(classSymbol, typeCache).Build(); + + RenderContext renderContext = new(classInfo, [classInfo], RenderOptions.TypeScript); + new TypescriptUserClassProxyRenderer(renderContext).Render(); + + AssertEx.EqualOrDiff(renderContext.ToString(), """ +export class C1 extends ProxyBase { + /** + * Initializes a new instance. + * @param jsObject - Object with member-initializers + */ + constructor(jsObject: C1.Initializer) { + super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); + } + + public get Name(): string { + return TypeShimConfig.exports.N1.C1Interop.get_Name(this.instance); + } + + public set Name(value: string) { + TypeShimConfig.exports.N1.C1Interop.set_Name(this.instance, value); + } +} + +"""); + } } diff --git a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Char.cs b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Char.cs index ab76c3e..4def7f7 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Char.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Char.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using System; using System.Collections.Generic; @@ -157,6 +157,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1.charCodeAt(0) })); } @@ -201,6 +204,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1 ? jsObject.P1.charCodeAt(0) : null })); } @@ -245,6 +251,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1.then(e => e.charCodeAt(0)) })); } @@ -289,6 +298,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1 ? jsObject.P1.then(e => e.charCodeAt(0)) : null })); } diff --git a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Delegates.cs b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Delegates.cs index cbc53c5..498b431 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Delegates.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Delegates.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using NUnit.Framework.Internal; using TypeShim.Generator.CSharp; @@ -1054,6 +1054,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: (arg0: number, arg1: ManagedObject) => jsObject.P1(String.fromCharCode(arg0), ProxyBase.fromHandle(UserClass, arg1)) })); } @@ -1108,6 +1111,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: (arg0: number) => { const retVal = jsObject.P1(String.fromCharCode(arg0)); return retVal instanceof UserClass ? retVal.instance : retVal } })); } @@ -1162,6 +1168,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: (arg0: number) => jsObject.P1(String.fromCharCode(arg0)) })); } @@ -1216,6 +1225,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: (arg0: ManagedObject) => jsObject.P1(ProxyBase.fromHandle(UserClass, arg0)) })); } diff --git a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_ParameterizedConstructors.cs b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_ParameterizedConstructors.cs index 15b8553..a5e111d 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_ParameterizedConstructors.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_ParameterizedConstructors.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using TypeShim.Generator.CSharp; using TypeShim.Generator.Parsing; @@ -598,6 +598,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); } @@ -641,6 +644,9 @@ public class C1(int i) AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(i: number, jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor(i, { ...jsObject })); } diff --git a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_ParameterlessConstructors.cs b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_ParameterlessConstructors.cs index 0664a90..d647f52 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_ParameterlessConstructors.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_ParameterlessConstructors.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using TypeShim.Generator.CSharp; using TypeShim.Generator.Parsing; @@ -38,6 +38,9 @@ public class C1() AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); } @@ -95,6 +98,9 @@ public class C1() // P2 is not mapped in the initializer ctor param since it has no setter. AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1 instanceof UserClass ? jsObject.P1.instance : jsObject.P1 })); } diff --git a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Properties.cs b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Properties.cs index 3f9835c..ce77b3a 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Properties.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Properties.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using System; using System.Collections.Generic; @@ -40,6 +40,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); } @@ -85,6 +88,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); } @@ -126,6 +132,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); } @@ -244,6 +253,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1 instanceof UserClass ? jsObject.P1.instance : jsObject.P1 })); } @@ -356,6 +368,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1 ? jsObject.P1 instanceof UserClass ? jsObject.P1.instance : jsObject.P1 : null })); } @@ -413,6 +428,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1.then(e => e instanceof UserClass ? e.instance : e) })); } @@ -470,6 +488,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); } @@ -526,6 +547,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1.map(e => e instanceof UserClass ? e.instance : e) })); } @@ -583,6 +607,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1.map(e => e ? e instanceof UserClass ? e.instance : e : null) })); } @@ -640,6 +667,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1 ? jsObject.P1.map(e => e instanceof UserClass ? e.instance : e) : null })); } @@ -697,6 +727,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1 ? jsObject.P1.map(e => e ? e instanceof UserClass ? e.instance : e : null) : null })); } @@ -754,6 +787,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1.then(e => e ? e instanceof UserClass ? e.instance : e : null) })); } @@ -811,6 +847,9 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { + /** + * @param jsObject - Object with member-initializers + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1 ? jsObject.P1.then(e => e ? e instanceof UserClass ? e.instance : e : null) : null })); } diff --git a/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs b/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs index d3fe622..249c06f 100644 --- a/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs +++ b/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs @@ -6,27 +6,30 @@ namespace TypeShim.Generator.Parsing; internal sealed partial class CommentInfoBuilder(ISymbol symbol) { - internal CommentInfo? Build() + internal CommentInfo? Build(MethodParameterInfo? initializerObject = null) { - string? xmlCommentString = symbol.GetDocumentationCommentXml(); - - if (string.IsNullOrWhiteSpace(xmlCommentString)) + string? xmlCommentString = symbol.GetDocumentationCommentXml() ?? string.Empty; + + if (string.IsNullOrWhiteSpace(xmlCommentString) && initializerObject == null) { return null; } try { - XDocument xmlDoc = XDocument.Parse(xmlCommentString.Replace("\n", " ").Replace("\r", " ")); + XDocument xmlDoc = string.IsNullOrWhiteSpace(xmlCommentString) + ? new XDocument(new XElement("member")) + : XDocument.Parse(xmlCommentString.Replace("\n", " ").Replace("\r", " ")); XElement? root = xmlDoc.Root; if (root == null) { return null; } + CommentInfo commentInfo = new() { Description = BuildFormattedTextElement(root, "summary"), Remarks = BuildFormattedTextElement(root, "remarks"), - Parameters = BuildParameters(root), + Parameters = BuildParameters(root, initializerObject), Returns = BuildReturns(root), Throws = BuildThrows(root) }; @@ -47,7 +50,7 @@ private static string BuildFormattedTextElement(XElement root, string elementNam return string.Empty; } - private static List BuildParameters(XElement root) + private static List BuildParameters(XElement root, MethodParameterInfo? initializerObject) { List parameters = []; foreach (XElement param in root.Elements("param")) @@ -65,6 +68,16 @@ private static List BuildParameters(XElement root) Description = description }); } + + if (initializerObject != null) + { + ParameterCommentInfo initializerParamInfo = new() + { + Name = initializerObject.Name, + Description = "Object with member-initializers" + }; + parameters.Add(initializerParamInfo); + } return parameters; } diff --git a/src/TypeShim.Generator/Parsing/ConstructorInfo.cs b/src/TypeShim.Generator/Parsing/ConstructorInfo.cs index 086bec6..e421880 100644 --- a/src/TypeShim.Generator/Parsing/ConstructorInfo.cs +++ b/src/TypeShim.Generator/Parsing/ConstructorInfo.cs @@ -1,4 +1,5 @@ -using TypeShim.Shared; +using TypeShim.Generator.Parsing; +using TypeShim.Shared; internal sealed class ConstructorInfo { @@ -7,6 +8,7 @@ internal sealed class ConstructorInfo internal required MethodParameterInfo? InitializerObject { get; init; } internal required PropertyInfo[] MemberInitializers { get; init; } internal required InteropTypeInfo Type { get; init; } + internal required CommentInfo? Comment { get; init; } internal bool IsParameterless => Parameters.Length == 0; internal bool AcceptsInitializer => MemberInitializers.Length > 0; diff --git a/src/TypeShim.Generator/Parsing/ConstructorInfoBuilder.cs b/src/TypeShim.Generator/Parsing/ConstructorInfoBuilder.cs index 074f96c..2fc557b 100644 --- a/src/TypeShim.Generator/Parsing/ConstructorInfoBuilder.cs +++ b/src/TypeShim.Generator/Parsing/ConstructorInfoBuilder.cs @@ -1,4 +1,5 @@ using Microsoft.CodeAnalysis; +using TypeShim.Generator.Parsing; using TypeShim.Shared; internal sealed class ConstructorInfoBuilder(INamedTypeSymbol classSymbol, IMethodSymbol memberMethod, InteropTypeInfoCache typeInfoCache) @@ -24,6 +25,7 @@ internal sealed class ConstructorInfoBuilder(INamedTypeSymbol classSymbol, IMeth InitializerObject = initializersObjectParameter, Type = typeInfoBuilder.Build(), MemberInitializers = [.. initializerProperties], + Comment = new CommentInfoBuilder(memberMethod).Build(initializersObjectParameter), }; } } \ No newline at end of file diff --git a/src/TypeShim.Generator/Typescript/TypeScriptMethodRenderer.cs b/src/TypeShim.Generator/Typescript/TypeScriptMethodRenderer.cs index 29c4753..9b674ca 100644 --- a/src/TypeShim.Generator/Typescript/TypeScriptMethodRenderer.cs +++ b/src/TypeShim.Generator/Typescript/TypeScriptMethodRenderer.cs @@ -28,6 +28,7 @@ internal void RenderProxyConstructor(ConstructorInfo? constructorInfo) } else { + TypeScriptJSDocRenderer.RenderJSDoc(ctx, constructorInfo.Comment); RenderConstructorSignature(); ctx.Append(' '); RenderConstructorBody();