From 3c520b0c5ee690f2d441ea78aa3f3758d6f818f3 Mon Sep 17 00:00:00 2001 From: Krzysztof Rodak Date: Tue, 23 Jun 2026 12:52:28 +0200 Subject: [PATCH] BridgeJS: Emit static members in declare global class declarations The `declare global { namespace ... }` class stub rendered every method without `static` and filtered properties to instance-only, so a `@JS static func` on a namespaced class was typed as an instance method and a `@JS static var` was omitted from the generated `.d.ts`. This was a type-only defect: the emitted JavaScript already exposes these members statically (and the class's namespace export entry types them correctly), so only TypeScript consumers were affected. Split static and instance members in this path: emit static methods with `static` and include static properties. This has been incorrect since the global namespace class stub was introduced, not a regression. The `Namespaces.Global` snapshot already exercises a namespaced class with `static func`/`static var` but had recorded the wrong output, so it is updated to the corrected declarations. --- .../BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift | 12 +++++++----- .../BridgeJSLinkTests/Namespaces.Global.d.ts | 3 ++- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index 8c9c20a14..01c390f26 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -3143,17 +3143,19 @@ extension BridgeJSLink { let sortedMethods = klass.methods.sorted { $0.name < $1.name } for method in sortedMethods { + let staticKeyword = method.effects.isStatic ? "static " : "" let methodSignature = - "\(method.name)\(renderTSSignatureCallback(method.parameters, method.returnType, method.effects));" + "\(staticKeyword)\(method.name)\(renderTSSignatureCallback(method.parameters, method.returnType, method.effects));" printer.write(methodSignature) } - let sortedProperties = klass.properties.filter { !$0.isStatic }.sorted { - $0.name < $1.name - } + let sortedProperties = klass.properties.sorted { $0.name < $1.name } for property in sortedProperties { + let staticKeyword = property.isStatic ? "static " : "" let readonly = property.isReadonly ? "readonly " : "" - printer.write("\(readonly)\(property.name): \(property.type.tsType);") + printer.write( + "\(staticKeyword)\(readonly)\(property.name): \(property.type.tsType);" + ) } printer.write("release(): void;") diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.d.ts index 1353220bc..d9af0c8eb 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.d.ts @@ -34,7 +34,8 @@ declare global { class Greeter { constructor(name: string); greet(): string; - makeDefault(): Greeter; + static makeDefault(): Greeter; + static readonly defaultGreeting: string; release(): void; } class UUID {