Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,11 @@ public class ExportSwift {
switch self {
case .enumStatic(let enumDef):
return property.callName(prefix: enumDef.swiftCallName)
case .classStatic, .classInstance:
case .classStatic(let klass):
// property.callName() would use staticContext (the ABI name) as prefix;
// use swiftCallName directly so the emitted expression is valid Swift.
return "\(klass.swiftCallName).\(property.name)"
case .classInstance:
return property.callName()
case .structStatic(let structDef):
return property.callName(prefix: structDef.swiftCallName)
Expand Down
37 changes: 14 additions & 23 deletions Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ public struct BridgeJSLink {
var classLines: [String] = []
var dtsExportLines: [String] = []
var dtsClassLines: [String] = []
var namespacedClassDtsExportEntries: [String: [String]] = [:]
var topLevelTypeLines: [String] = []
var topLevelDtsTypeLines: [String] = []
var importObjectBuilders: [ImportObjectBuilder] = []
Expand Down Expand Up @@ -161,13 +162,14 @@ public struct BridgeJSLink {
for klass in skeleton.classes {
let (jsType, dtsType, dtsExportEntry) = try renderExportedClass(klass)
data.classLines.append(contentsOf: jsType)
data.dtsClassLines.append(contentsOf: dtsType)

if klass.namespace == nil {
data.exportsLines.append("\(klass.name),")
data.dtsExportLines.append(contentsOf: dtsExportEntry)
} else {
data.namespacedClassDtsExportEntries[klass.name] = dtsExportEntry
}

data.dtsClassLines.append(contentsOf: dtsType)
}

// Process enums - collect top-level definitions and export entries
Expand Down Expand Up @@ -884,32 +886,21 @@ public struct BridgeJSLink {
printer.write(lines: generateImportedTypeDefinitions())

// Exports type
let hierarchicalExportLines = namespaceBuilder.buildHierarchicalExportsType(
exportedSkeletons: exportedSkeletons,
renderClassEntry: { klass in
data.namespacedClassDtsExportEntries[klass.name] ?? []
},
renderFunctionSignature: { function in
"\(function.name)\(self.renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));"
}
)
printer.write("export type Exports = {")
printer.indent {
// Add non-namespaced items
printer.write(lines: data.dtsExportLines)

// Add hierarchical namespaced items
let hierarchicalLines = namespaceBuilder.buildHierarchicalExportsType(
exportedSkeletons: exportedSkeletons,
renderClassEntry: { klass in
let printer = CodeFragmentPrinter()
printer.write("\(klass.name): {")
printer.indent {
if let constructor = klass.constructor {
printer.write(
"new\(self.renderTSSignature(parameters: constructor.parameters, returnType: .swiftHeapObject(klass.name), effects: constructor.effects));"
)
}
}
printer.write("}")
return printer.lines
},
renderFunctionSignature: { function in
"\(function.name)\(self.renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));"
}
)
printer.write(lines: hierarchicalLines)
printer.write(lines: hierarchicalExportLines)
}
printer.write("}")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@
func changeName(name: String) {
self.name = name
}

// Static methods and properties on a namespaced class must land on the
// class's namespace entry (alongside `new`), not on the instance
// interface and not silently dropped. Regression test for the
// `@JS(namespace:)` + `@JS static func` bug where the hierarchical
// exports builder only emitted the constructor.
@JS static func makeDefault() -> Greeter {
return Greeter(name: "World")
}

@JS static var defaultGreeting: String { "Hello, world!" }
}

@JS(namespace: "Utils.Converters") class Converter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,28 @@

}
}
},
{
"abiName" : "bjs___Swift_Foundation_Greeter_static_makeDefault",
"effects" : {
"isAsync" : false,
"isStatic" : true,
"isThrows" : false
},
"name" : "makeDefault",
"parameters" : [

],
"returnType" : {
"swiftHeapObject" : {
"_0" : "Greeter"
}
},
"staticContext" : {
"className" : {
"_0" : "__Swift_Foundation_Greeter"
}
}
}
],
"name" : "Greeter",
Expand All @@ -46,7 +68,21 @@
"Foundation"
],
"properties" : [
{
"isReadonly" : true,
"isStatic" : true,
"name" : "defaultGreeting",
"staticContext" : {
"className" : {
"_0" : "__Swift_Foundation_Greeter"
}
},
"type" : {
"string" : {

}
}
}
],
"swiftCallName" : "Greeter"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,28 @@ public func _bjs___Swift_Foundation_Greeter_greet(_ _self: UnsafeMutableRawPoint
#endif
}

@_expose(wasm, "bjs___Swift_Foundation_Greeter_static_makeDefault")
@_cdecl("bjs___Swift_Foundation_Greeter_static_makeDefault")
public func _bjs___Swift_Foundation_Greeter_static_makeDefault() -> UnsafeMutableRawPointer {
#if arch(wasm32)
let ret = Greeter.makeDefault()
return ret.bridgeJSLowerReturn()
#else
fatalError("Only available on WebAssembly")
#endif
}

@_expose(wasm, "bjs___Swift_Foundation_Greeter_static_defaultGreeting_get")
@_cdecl("bjs___Swift_Foundation_Greeter_static_defaultGreeting_get")
public func _bjs___Swift_Foundation_Greeter_static_defaultGreeting_get() -> Void {
#if arch(wasm32)
let ret = Greeter.defaultGreeting
return ret.bridgeJSLowerReturn()
#else
fatalError("Only available on WebAssembly")
#endif
}

@_expose(wasm, "bjs___Swift_Foundation_Greeter_deinit")
@_cdecl("bjs___Swift_Foundation_Greeter_deinit")
public func _bjs___Swift_Foundation_Greeter_deinit(_ pointer: UnsafeMutableRawPointer) -> Void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,28 @@

}
}
},
{
"abiName" : "bjs___Swift_Foundation_Greeter_static_makeDefault",
"effects" : {
"isAsync" : false,
"isStatic" : true,
"isThrows" : false
},
"name" : "makeDefault",
"parameters" : [

],
"returnType" : {
"swiftHeapObject" : {
"_0" : "Greeter"
}
},
"staticContext" : {
"className" : {
"_0" : "__Swift_Foundation_Greeter"
}
}
}
],
"name" : "Greeter",
Expand All @@ -46,7 +68,21 @@
"Foundation"
],
"properties" : [
{
"isReadonly" : true,
"isStatic" : true,
"name" : "defaultGreeting",
"staticContext" : {
"className" : {
"_0" : "__Swift_Foundation_Greeter"
}
},
"type" : {
"string" : {

}
}
}
],
"swiftCallName" : "Greeter"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,28 @@ public func _bjs___Swift_Foundation_Greeter_greet(_ _self: UnsafeMutableRawPoint
#endif
}

@_expose(wasm, "bjs___Swift_Foundation_Greeter_static_makeDefault")
@_cdecl("bjs___Swift_Foundation_Greeter_static_makeDefault")
public func _bjs___Swift_Foundation_Greeter_static_makeDefault() -> UnsafeMutableRawPointer {
#if arch(wasm32)
let ret = Greeter.makeDefault()
return ret.bridgeJSLowerReturn()
#else
fatalError("Only available on WebAssembly")
#endif
}

@_expose(wasm, "bjs___Swift_Foundation_Greeter_static_defaultGreeting_get")
@_cdecl("bjs___Swift_Foundation_Greeter_static_defaultGreeting_get")
public func _bjs___Swift_Foundation_Greeter_static_defaultGreeting_get() -> Void {
#if arch(wasm32)
let ret = Greeter.defaultGreeting
return ret.bridgeJSLowerReturn()
#else
fatalError("Only available on WebAssembly")
#endif
}

@_expose(wasm, "bjs___Swift_Foundation_Greeter_deinit")
@_cdecl("bjs___Swift_Foundation_Greeter_deinit")
public func _bjs___Swift_Foundation_Greeter_deinit(_ pointer: UnsafeMutableRawPointer) -> Void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ declare global {
class Greeter {
constructor(name: string);
greet(): string;
makeDefault(): Greeter;
release(): void;
}
class UUID {
Expand Down Expand Up @@ -87,6 +88,8 @@ export type Exports = {
Foundation: {
Greeter: {
new(name: string): Greeter;
makeDefault(): Greeter;
readonly defaultGreeting: string;
}
UUID: {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,16 @@ export async function createInstantiator(options, swift) {
tmpRetString = undefined;
return ret;
}
static makeDefault() {
const ret = instance.exports.bjs___Swift_Foundation_Greeter_static_makeDefault();
return Greeter.__construct(ret);
}
static get defaultGreeting() {
instance.exports.bjs___Swift_Foundation_Greeter_static_defaultGreeting_get();
const ret = tmpRetString;
tmpRetString = undefined;
return ret;
}
}
class Converter extends SwiftHeapObject {
static __construct(ptr) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ export type Exports = {
Foundation: {
Greeter: {
new(name: string): Greeter;
makeDefault(): Greeter;
readonly defaultGreeting: string;
}
UUID: {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,16 @@ export async function createInstantiator(options, swift) {
tmpRetString = undefined;
return ret;
}
static makeDefault() {
const ret = instance.exports.bjs___Swift_Foundation_Greeter_static_makeDefault();
return Greeter.__construct(ret);
}
static get defaultGreeting() {
instance.exports.bjs___Swift_Foundation_Greeter_static_defaultGreeting_get();
const ret = tmpRetString;
tmpRetString = undefined;
return ret;
}
}
class Converter extends SwiftHeapObject {
static __construct(ptr) {
Expand Down
6 changes: 6 additions & 0 deletions Tests/BridgeJSRuntimeTests/ExportAPITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,12 @@ class UUID {
@JS func uuidString() -> String {
return value
}

@JS static func fromValue(_ value: String) -> UUID {
return UUID(value: value)
}

@JS static var placeholder: String { "00000000-0000-0000-0000-000000000000" }
}

@JS func createUUID(value: String) -> UUID {
Expand Down
22 changes: 22 additions & 0 deletions Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8602,6 +8602,28 @@ public func _bjs___Swift_Foundation_UUID_uuidString(_ _self: UnsafeMutableRawPoi
#endif
}

@_expose(wasm, "bjs___Swift_Foundation_UUID_static_fromValue")
@_cdecl("bjs___Swift_Foundation_UUID_static_fromValue")
public func _bjs___Swift_Foundation_UUID_static_fromValue(_ valueBytes: Int32, _ valueLength: Int32) -> UnsafeMutableRawPointer {
#if arch(wasm32)
let ret = UUID.fromValue(_: String.bridgeJSLiftParameter(valueBytes, valueLength))
return ret.bridgeJSLowerReturn()
#else
fatalError("Only available on WebAssembly")
#endif
}

@_expose(wasm, "bjs___Swift_Foundation_UUID_static_placeholder_get")
@_cdecl("bjs___Swift_Foundation_UUID_static_placeholder_get")
public func _bjs___Swift_Foundation_UUID_static_placeholder_get() -> Void {
#if arch(wasm32)
let ret = UUID.placeholder
return ret.bridgeJSLowerReturn()
#else
fatalError("Only available on WebAssembly")
#endif
}

@_expose(wasm, "bjs___Swift_Foundation_UUID_deinit")
@_cdecl("bjs___Swift_Foundation_UUID_deinit")
public func _bjs___Swift_Foundation_UUID_deinit(_ pointer: UnsafeMutableRawPointer) -> Void {
Expand Down
Loading
Loading