From 2e7f9bfcfbaf9b124ceca2127fcfcbe52874d143 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 28 Feb 2026 22:04:52 +0000 Subject: [PATCH 01/14] Initial plan From 5cfb314fd5c47105a1ce2644d6ce67b459023353 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 28 Feb 2026 22:07:51 +0000 Subject: [PATCH 02/14] Add CommentInfo to ConstructorInfo and render JSDoc on proxy constructor Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com> --- .../TypeScript/TypeScriptJSDocTests.cs | 193 ++++++++++++++++++ .../Parsing/ConstructorInfo.cs | 4 +- .../Parsing/ConstructorInfoBuilder.cs | 2 + .../Typescript/TypeScriptMethodRenderer.cs | 1 + 4 files changed, 199 insertions(+), 1 deletion(-) diff --git a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs index 8643fc86..7bbb5b3c 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs @@ -1943,4 +1943,197 @@ 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); + } +} + +"""); + } } diff --git a/src/TypeShim.Generator/Parsing/ConstructorInfo.cs b/src/TypeShim.Generator/Parsing/ConstructorInfo.cs index 086bec6f..e4218807 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 074f96c8..5b607fcf 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(), }; } } \ No newline at end of file diff --git a/src/TypeShim.Generator/Typescript/TypeScriptMethodRenderer.cs b/src/TypeShim.Generator/Typescript/TypeScriptMethodRenderer.cs index 29c4753b..9b674cac 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(); From 8456822ff3b4265234fa83309ab496e530127c60 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 28 Feb 2026 22:10:05 +0000 Subject: [PATCH 03/14] Add CommentInfo to ConstructorInfo and render JSDoc on proxy constructor Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com> --- .../obj\\Debug/\\package.g.props" | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 "sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" diff --git "a/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" "b/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" new file mode 100644 index 00000000..b8e0bab4 --- /dev/null +++ "b/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" @@ -0,0 +1,31 @@ + + + + @typeshim/demo + 1.0.0 + + npm run dev -w @typeshim/app + npm run dev -w @typeshim/app + echo "Error: no test specified" && exit 1 + npm run build -w @typeshim/wasm-exports + npm run build -w @typeshim/people-ui + npm run build -w @typeshim/app + npm run build:exports && npm run build:people && npm run build:app + [] + + ISC + true + [ + "@typeshim/*" +] + ^18.3.1 + ^18.3.1 + ^19.2.6 + ^19.2.3 + ^4.3.4 + ^5.9.3 + 7.2.4 + ^1.6.0 + ^3.5.0 + + \ No newline at end of file From 4474e6c52c14a493a725dafa78066bc0eeb1478d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 28 Feb 2026 22:28:08 +0000 Subject: [PATCH 04/14] Remove accidentally committed build artifact and add obj/ to .gitignore Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com> --- sample/TypeShim.Sample.Client/.gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sample/TypeShim.Sample.Client/.gitignore b/sample/TypeShim.Sample.Client/.gitignore index b7447368..0f1a682f 100644 --- a/sample/TypeShim.Sample.Client/.gitignore +++ b/sample/TypeShim.Sample.Client/.gitignore @@ -126,3 +126,8 @@ scripts/*.tmp # Git merge / rebase artifacts # ----------------------------- *.orig + +# ----------------------------- +# MSBuild / VS project outputs +# ----------------------------- +obj/ From 62cab19f2348af28c6a27862982b0ffe85c0e2fb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 28 Feb 2026 22:29:31 +0000 Subject: [PATCH 05/14] Remove accidentally committed build artifact from git tracking Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com> --- sample/TypeShim.Sample.Client/.gitignore | 1 + .../obj\\Debug/\\package.g.props" | 31 ------------------- 2 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 "sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" diff --git a/sample/TypeShim.Sample.Client/.gitignore b/sample/TypeShim.Sample.Client/.gitignore index 0f1a682f..15ec882c 100644 --- a/sample/TypeShim.Sample.Client/.gitignore +++ b/sample/TypeShim.Sample.Client/.gitignore @@ -131,3 +131,4 @@ scripts/*.tmp # MSBuild / VS project outputs # ----------------------------- obj/ +obj[\\]Debug/ diff --git "a/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" "b/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" deleted file mode 100644 index b8e0bab4..00000000 --- "a/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" +++ /dev/null @@ -1,31 +0,0 @@ - - - - @typeshim/demo - 1.0.0 - - npm run dev -w @typeshim/app - npm run dev -w @typeshim/app - echo "Error: no test specified" && exit 1 - npm run build -w @typeshim/wasm-exports - npm run build -w @typeshim/people-ui - npm run build -w @typeshim/app - npm run build:exports && npm run build:people && npm run build:app - [] - - ISC - true - [ - "@typeshim/*" -] - ^18.3.1 - ^18.3.1 - ^19.2.6 - ^19.2.3 - ^4.3.4 - ^5.9.3 - 7.2.4 - ^1.6.0 - ^3.5.0 - - \ No newline at end of file From 365782accdfafd51763605e9f319770cf065b774 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 28 Feb 2026 22:57:04 +0000 Subject: [PATCH 06/14] Fix bold tag in test, add initializerObject param to CommentInfoBuilder, revert client gitignore Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com> --- sample/TypeShim.Sample.Client/.gitignore | 6 ------ .../TypeScript/TypeScriptJSDocTests.cs | 4 ++-- .../Parsing/CommentInfoBuilder.cs | 13 +++++++++++-- .../Parsing/ConstructorInfoBuilder.cs | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/sample/TypeShim.Sample.Client/.gitignore b/sample/TypeShim.Sample.Client/.gitignore index 15ec882c..b7447368 100644 --- a/sample/TypeShim.Sample.Client/.gitignore +++ b/sample/TypeShim.Sample.Client/.gitignore @@ -126,9 +126,3 @@ scripts/*.tmp # Git merge / rebase artifacts # ----------------------------- *.orig - -# ----------------------------- -# MSBuild / VS project outputs -# ----------------------------- -obj/ -obj[\\]Debug/ diff --git a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs index 7bbb5b3c..08bc4b57 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs @@ -1954,7 +1954,7 @@ namespace N1; public class C1 { /// - /// Initializes a new instance with bold formatting. + /// Initializes a new instance with bold formatting. /// public C1(string name) {} public string Name => name; @@ -1975,7 +1975,7 @@ public C1(string name) {} AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * Initializes a new instance with `bold` formatting. + * Initializes a new instance with **bold** formatting. */ constructor(name: string) { super(TypeShimConfig.exports.N1.C1Interop.ctor(name)); diff --git a/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs b/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs index d3fe622e..0abb8c8a 100644 --- a/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs +++ b/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs @@ -6,7 +6,7 @@ namespace TypeShim.Generator.Parsing; internal sealed partial class CommentInfoBuilder(ISymbol symbol) { - internal CommentInfo? Build() + internal CommentInfo? Build(MethodParameterInfo? initializerObject = null) { string? xmlCommentString = symbol.GetDocumentationCommentXml(); @@ -22,11 +22,20 @@ internal sealed partial class CommentInfoBuilder(ISymbol symbol) { return null; } + List parameters = BuildParameters(root); + if (initializerObject is not null) + { + parameters.Add(new ParameterCommentInfo + { + Name = initializerObject.Name, + Description = "Property values to initialize the instance with" + }); + } CommentInfo commentInfo = new() { Description = BuildFormattedTextElement(root, "summary"), Remarks = BuildFormattedTextElement(root, "remarks"), - Parameters = BuildParameters(root), + Parameters = parameters, Returns = BuildReturns(root), Throws = BuildThrows(root) }; diff --git a/src/TypeShim.Generator/Parsing/ConstructorInfoBuilder.cs b/src/TypeShim.Generator/Parsing/ConstructorInfoBuilder.cs index 5b607fcf..2fc557b9 100644 --- a/src/TypeShim.Generator/Parsing/ConstructorInfoBuilder.cs +++ b/src/TypeShim.Generator/Parsing/ConstructorInfoBuilder.cs @@ -25,7 +25,7 @@ internal sealed class ConstructorInfoBuilder(INamedTypeSymbol classSymbol, IMeth InitializerObject = initializersObjectParameter, Type = typeInfoBuilder.Build(), MemberInitializers = [.. initializerProperties], - Comment = new CommentInfoBuilder(memberMethod).Build(), + Comment = new CommentInfoBuilder(memberMethod).Build(initializersObjectParameter), }; } } \ No newline at end of file From 838e24126095758e6d48392271d21b458a7117d2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 28 Feb 2026 23:33:20 +0000 Subject: [PATCH 07/14] Add test for constructor JSDoc with inserted jsObject param when class has settable property Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com> --- .../TypeScript/TypeScriptJSDocTests.cs | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs index 08bc4b57..64f5d5dc 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs @@ -2134,6 +2134,56 @@ public get Name(): string { } } +"""); + } + + [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 - Property values to initialize the instance with + */ + 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); + } +} + """); } } From cdcecae886e64327da5a813b42add7daf518332a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Mar 2026 00:06:01 +0000 Subject: [PATCH 08/14] Emit JSDoc for initializer-object constructor even when no XML doc comment is present Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com> --- .../TypeScript/TypeScriptJSDocTests.cs | 3 ++ ...eScriptUserClassProxyRendererTests_Char.cs | 14 ++++++- ...ptUserClassProxyRendererTests_Delegates.cs | 14 ++++++- ...RendererTests_ParameterizedConstructors.cs | 8 +++- ...RendererTests_ParameterlessConstructors.cs | 8 +++- ...tUserClassProxyRendererTests_Properties.cs | 41 ++++++++++++++++++- .../Parsing/CommentInfoBuilder.cs | 37 +++++++++++------ 7 files changed, 108 insertions(+), 17 deletions(-) diff --git a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs index 64f5d5dc..7fd6f9dc 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 - Property values to initialize the instance with + */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); } diff --git a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Char.cs b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Char.cs index ab76c3e6..17868b40 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 cbc53c51..2a1d9a1e 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 15b85532..20cbe5dd 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 0664a90d..87947328 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 3f9835c0..9dc0a55a 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 - Property values to initialize the instance with + */ 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 0abb8c8a..6ef2f8bb 100644 --- a/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs +++ b/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs @@ -8,21 +8,34 @@ internal sealed partial class CommentInfoBuilder(ISymbol symbol) { 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 is null) { return null; } try { - XDocument xmlDoc = XDocument.Parse(xmlCommentString.Replace("\n", " ").Replace("\r", " ")); - XElement? root = xmlDoc.Root; - if (root == null) + List parameters = []; + string description = string.Empty; + string remarks = string.Empty; + string? returns = null; + IReadOnlyCollection throws = []; + + if (!string.IsNullOrWhiteSpace(xmlCommentString)) { - return null; + XDocument xmlDoc = XDocument.Parse(xmlCommentString.Replace("\n", " ").Replace("\r", " ")); + XElement? root = xmlDoc.Root; + if (root != null) + { + parameters = BuildParameters(root); + description = BuildFormattedTextElement(root, "summary"); + remarks = BuildFormattedTextElement(root, "remarks"); + returns = BuildReturns(root); + throws = BuildThrows(root); + } } - List parameters = BuildParameters(root); + if (initializerObject is not null) { parameters.Add(new ParameterCommentInfo @@ -33,11 +46,11 @@ internal sealed partial class CommentInfoBuilder(ISymbol symbol) } CommentInfo commentInfo = new() { - Description = BuildFormattedTextElement(root, "summary"), - Remarks = BuildFormattedTextElement(root, "remarks"), + Description = description, + Remarks = remarks, Parameters = parameters, - Returns = BuildReturns(root), - Throws = BuildThrows(root) + Returns = returns, + Throws = throws }; return commentInfo.IsEmpty() ? null : commentInfo; } From 9bdc5f1429e7531050b100c2db83c88552e6fbda Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Mar 2026 00:08:25 +0000 Subject: [PATCH 09/14] Support comments on exported constructors Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com> --- .../obj\\Debug/\\package.g.props" | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 "sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" diff --git "a/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" "b/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" new file mode 100644 index 00000000..b8e0bab4 --- /dev/null +++ "b/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" @@ -0,0 +1,31 @@ + + + + @typeshim/demo + 1.0.0 + + npm run dev -w @typeshim/app + npm run dev -w @typeshim/app + echo "Error: no test specified" && exit 1 + npm run build -w @typeshim/wasm-exports + npm run build -w @typeshim/people-ui + npm run build -w @typeshim/app + npm run build:exports && npm run build:people && npm run build:app + [] + + ISC + true + [ + "@typeshim/*" +] + ^18.3.1 + ^18.3.1 + ^19.2.6 + ^19.2.3 + ^4.3.4 + ^5.9.3 + 7.2.4 + ^1.6.0 + ^3.5.0 + + \ No newline at end of file From a1f0888f886880917f2f9329c565f160634c63fa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Mar 2026 00:26:23 +0000 Subject: [PATCH 10/14] Simplify CommentInfoBuilder.Build, use == null, and remove package.g.props again Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com> --- .../obj\\Debug/\\package.g.props" | 31 ---------------- .../Parsing/CommentInfoBuilder.cs | 37 +++++++------------ 2 files changed, 13 insertions(+), 55 deletions(-) delete mode 100644 "sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" diff --git "a/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" "b/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" deleted file mode 100644 index b8e0bab4..00000000 --- "a/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" +++ /dev/null @@ -1,31 +0,0 @@ - - - - @typeshim/demo - 1.0.0 - - npm run dev -w @typeshim/app - npm run dev -w @typeshim/app - echo "Error: no test specified" && exit 1 - npm run build -w @typeshim/wasm-exports - npm run build -w @typeshim/people-ui - npm run build -w @typeshim/app - npm run build:exports && npm run build:people && npm run build:app - [] - - ISC - true - [ - "@typeshim/*" -] - ^18.3.1 - ^18.3.1 - ^19.2.6 - ^19.2.3 - ^4.3.4 - ^5.9.3 - 7.2.4 - ^1.6.0 - ^3.5.0 - - \ No newline at end of file diff --git a/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs b/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs index 6ef2f8bb..e533c059 100644 --- a/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs +++ b/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs @@ -10,33 +10,22 @@ internal sealed partial class CommentInfoBuilder(ISymbol symbol) { string? xmlCommentString = symbol.GetDocumentationCommentXml() ?? string.Empty; - if (string.IsNullOrWhiteSpace(xmlCommentString) && initializerObject is null) + if (string.IsNullOrWhiteSpace(xmlCommentString) && initializerObject == null) { return null; } try { - List parameters = []; - string description = string.Empty; - string remarks = string.Empty; - string? returns = null; - IReadOnlyCollection throws = []; - - if (!string.IsNullOrWhiteSpace(xmlCommentString)) + XDocument xmlDoc = string.IsNullOrWhiteSpace(xmlCommentString) + ? new XDocument(new XElement("member")) + : XDocument.Parse(xmlCommentString.Replace("\n", " ").Replace("\r", " ")); + XElement? root = xmlDoc.Root; + if (root == null) { - XDocument xmlDoc = XDocument.Parse(xmlCommentString.Replace("\n", " ").Replace("\r", " ")); - XElement? root = xmlDoc.Root; - if (root != null) - { - parameters = BuildParameters(root); - description = BuildFormattedTextElement(root, "summary"); - remarks = BuildFormattedTextElement(root, "remarks"); - returns = BuildReturns(root); - throws = BuildThrows(root); - } + return null; } - - if (initializerObject is not null) + List parameters = BuildParameters(root); + if (initializerObject != null) { parameters.Add(new ParameterCommentInfo { @@ -46,11 +35,11 @@ internal sealed partial class CommentInfoBuilder(ISymbol symbol) } CommentInfo commentInfo = new() { - Description = description, - Remarks = remarks, + Description = BuildFormattedTextElement(root, "summary"), + Remarks = BuildFormattedTextElement(root, "remarks"), Parameters = parameters, - Returns = returns, - Throws = throws + Returns = BuildReturns(root), + Throws = BuildThrows(root) }; return commentInfo.IsEmpty() ? null : commentInfo; } From b2af582d04c8669f76238d67b1b04ef4eaeb07bb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Mar 2026 00:28:54 +0000 Subject: [PATCH 11/14] Co-authored-by: ArcadeMode <5969155+ArcadeMode@users.noreply.github.com> --- .../obj\\Debug/\\package.g.props" | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 "sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" diff --git "a/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" "b/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" new file mode 100644 index 00000000..b8e0bab4 --- /dev/null +++ "b/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" @@ -0,0 +1,31 @@ + + + + @typeshim/demo + 1.0.0 + + npm run dev -w @typeshim/app + npm run dev -w @typeshim/app + echo "Error: no test specified" && exit 1 + npm run build -w @typeshim/wasm-exports + npm run build -w @typeshim/people-ui + npm run build -w @typeshim/app + npm run build:exports && npm run build:people && npm run build:app + [] + + ISC + true + [ + "@typeshim/*" +] + ^18.3.1 + ^18.3.1 + ^19.2.6 + ^19.2.3 + ^4.3.4 + ^5.9.3 + 7.2.4 + ^1.6.0 + ^3.5.0 + + \ No newline at end of file From f9d22f1ace78cc7ee5d50f85629c866d53827b58 Mon Sep 17 00:00:00 2001 From: Marc Zwart Date: Sun, 1 Mar 2026 10:44:00 +0100 Subject: [PATCH 12/14] Delete sample/TypeShim.Sample.Client/obj\Debug/\package.g.props --- .../obj\\Debug/\\package.g.props" | 31 ------------------- 1 file changed, 31 deletions(-) delete mode 100644 "sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" diff --git "a/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" "b/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" deleted file mode 100644 index b8e0bab4..00000000 --- "a/sample/TypeShim.Sample.Client/obj\\Debug/\\package.g.props" +++ /dev/null @@ -1,31 +0,0 @@ - - - - @typeshim/demo - 1.0.0 - - npm run dev -w @typeshim/app - npm run dev -w @typeshim/app - echo "Error: no test specified" && exit 1 - npm run build -w @typeshim/wasm-exports - npm run build -w @typeshim/people-ui - npm run build -w @typeshim/app - npm run build:exports && npm run build:people && npm run build:app - [] - - ISC - true - [ - "@typeshim/*" -] - ^18.3.1 - ^18.3.1 - ^19.2.6 - ^19.2.3 - ^4.3.4 - ^5.9.3 - 7.2.4 - ^1.6.0 - ^3.5.0 - - \ No newline at end of file From 1ce5fc14eb89615be48a750b3c1f29d4be9e78b1 Mon Sep 17 00:00:00 2001 From: Marc Zwart Date: Sun, 1 Mar 2026 11:08:44 +0100 Subject: [PATCH 13/14] minor readability tweak --- .../Parsing/CommentInfoBuilder.cs | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs b/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs index e533c059..ebdb06b8 100644 --- a/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs +++ b/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs @@ -24,20 +24,12 @@ internal sealed partial class CommentInfoBuilder(ISymbol symbol) { return null; } - List parameters = BuildParameters(root); - if (initializerObject != null) - { - parameters.Add(new ParameterCommentInfo - { - Name = initializerObject.Name, - Description = "Property values to initialize the instance with" - }); - } + CommentInfo commentInfo = new() { Description = BuildFormattedTextElement(root, "summary"), Remarks = BuildFormattedTextElement(root, "remarks"), - Parameters = parameters, + Parameters = BuildParameters(root, initializerObject), Returns = BuildReturns(root), Throws = BuildThrows(root) }; @@ -58,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")) @@ -76,6 +68,16 @@ private static List BuildParameters(XElement root) Description = description }); } + + if (initializerObject != null) + { + ParameterCommentInfo initializerParamInfo = new() + { + Name = initializerObject.Name, + Description = "Property values to initialize the instance with" + }; + parameters.Add(initializerParamInfo); + } return parameters; } From 2069c7dbd71e3eb71e8e47c04cfe99120b102c5a Mon Sep 17 00:00:00 2001 From: Marc Zwart Date: Sun, 1 Mar 2026 13:14:43 +0100 Subject: [PATCH 14/14] change default description --- .../TypeScript/TypeScriptJSDocTests.cs | 4 +-- ...eScriptUserClassProxyRendererTests_Char.cs | 8 +++--- ...ptUserClassProxyRendererTests_Delegates.cs | 8 +++--- ...RendererTests_ParameterizedConstructors.cs | 4 +-- ...RendererTests_ParameterlessConstructors.cs | 4 +-- ...tUserClassProxyRendererTests_Properties.cs | 26 +++++++++---------- .../Parsing/CommentInfoBuilder.cs | 2 +- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs index 7fd6f9dc..2bbd2532 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptJSDocTests.cs @@ -228,7 +228,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @param jsObject - Object with member-initializers */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); @@ -2172,7 +2172,7 @@ public C1() {} export class C1 extends ProxyBase { /** * Initializes a new instance. - * @param jsObject - Property values to initialize the instance with + * @param jsObject - Object with member-initializers */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); diff --git a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Char.cs b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Char.cs index 17868b40..4def7f7b 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Char.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Char.cs @@ -158,7 +158,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @param jsObject - Object with member-initializers */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject, P1: jsObject.P1.charCodeAt(0) })); @@ -205,7 +205,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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 })); @@ -252,7 +252,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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)) })); @@ -299,7 +299,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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 2a1d9a1e..498b431b 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Delegates.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Delegates.cs @@ -1055,7 +1055,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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)) })); @@ -1112,7 +1112,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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 } })); @@ -1169,7 +1169,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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)) })); @@ -1226,7 +1226,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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 20cbe5dd..a5e111d2 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_ParameterizedConstructors.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_ParameterizedConstructors.cs @@ -599,7 +599,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @param jsObject - Object with member-initializers */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); @@ -645,7 +645,7 @@ public class C1(int i) AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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 87947328..d647f52c 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_ParameterlessConstructors.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_ParameterlessConstructors.cs @@ -39,7 +39,7 @@ public class C1() AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @param jsObject - Object with member-initializers */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); @@ -99,7 +99,7 @@ public class C1() AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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 9dc0a55a..ce77b3a4 100644 --- a/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Properties.cs +++ b/src/TypeShim.Generator.Tests/TypeScript/TypeScriptUserClassProxyRendererTests_Properties.cs @@ -41,7 +41,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @param jsObject - Object with member-initializers */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); @@ -89,7 +89,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @param jsObject - Object with member-initializers */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); @@ -133,7 +133,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @param jsObject - Object with member-initializers */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); @@ -254,7 +254,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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 })); @@ -369,7 +369,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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 })); @@ -429,7 +429,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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) })); @@ -489,7 +489,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @param jsObject - Object with member-initializers */ constructor(jsObject: C1.Initializer) { super(TypeShimConfig.exports.N1.C1Interop.ctor({ ...jsObject })); @@ -548,7 +548,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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) })); @@ -608,7 +608,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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) })); @@ -668,7 +668,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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 })); @@ -728,7 +728,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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 })); @@ -788,7 +788,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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) })); @@ -848,7 +848,7 @@ public class C1 AssertEx.EqualOrDiff(renderContext.ToString(), """ export class C1 extends ProxyBase { /** - * @param jsObject - Property values to initialize the instance with + * @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 ebdb06b8..249c06f3 100644 --- a/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs +++ b/src/TypeShim.Generator/Parsing/CommentInfoBuilder.cs @@ -74,7 +74,7 @@ private static List BuildParameters(XElement root, MethodP ParameterCommentInfo initializerParamInfo = new() { Name = initializerObject.Name, - Description = "Property values to initialize the instance with" + Description = "Object with member-initializers" }; parameters.Add(initializerParamInfo); }