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);
}