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
18 changes: 9 additions & 9 deletions Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,9 @@ public class ExportSwift {
case .enumStatic(let enumDef):
return enumDef.name
case .classStatic(let klass), .classInstance(let klass):
return klass.name
return klass.abiName
case .structStatic(let structDef):
return structDef.name
return structDef.abiName
}
}

Expand Down Expand Up @@ -653,7 +653,7 @@ public class ExportSwift {

do {
let funcDecl = SwiftCodePattern.buildExposedFunctionDecl(
abiName: "bjs_\(klass.name)_deinit",
abiName: "bjs_\(klass.abiName)_deinit",
signature: SwiftSignatureBuilder.buildABIFunctionSignature(
abiParameters: [("pointer", .pointer)],
returnType: nil
Expand Down Expand Up @@ -686,8 +686,8 @@ public class ExportSwift {
/// fileprivate func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32
/// ```
func renderConvertibleToJSValueExtension(klass: ExportedClass) -> [DeclSyntax] {
let wrapFunctionName = "_bjs_\(klass.name)_wrap"
let externFunctionName = "bjs_\(klass.name)_wrap"
let wrapFunctionName = "_bjs_\(klass.abiName)_wrap"
let externFunctionName = "bjs_\(klass.abiName)_wrap"

// If the class has an explicit access control, we need to add it to the extension declaration.
let accessControl = klass.explicitAccessControl.map { "\($0) " } ?? ""
Expand Down Expand Up @@ -1087,10 +1087,10 @@ struct StructCodegen {
func renderStructHelpers(_ structDef: ExportedStruct) -> [DeclSyntax] {
let typeName = structDef.swiftCallName

let lowerExternName = "swift_js_struct_lower_\(structDef.name)"
let liftExternName = "swift_js_struct_lift_\(structDef.name)"
let lowerFunctionName = "_bjs_struct_lower_\(structDef.name)"
let liftFunctionName = "_bjs_struct_lift_\(structDef.name)"
let lowerExternName = "swift_js_struct_lower_\(structDef.abiName)"
let liftExternName = "swift_js_struct_lift_\(structDef.abiName)"
let lowerFunctionName = "_bjs_struct_lower_\(structDef.abiName)"
let liftFunctionName = "_bjs_struct_lift_\(structDef.abiName)"

let printer = CodeFragmentPrinter()
printer.write("extension \(typeName): _BridgedSwiftStruct {")
Expand Down
42 changes: 26 additions & 16 deletions Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1060,9 +1060,10 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
switch state {
case .topLevel:
staticContext = nil
case .classBody(let className, _):
case .classBody(_, let classKey):
if isStatic {
staticContext = .className(className)
let classAbiName = exportedClassByName[classKey]?.abiName ?? "unknown"
staticContext = .className(classAbiName)
} else {
staticContext = nil
}
Expand All @@ -1077,20 +1078,21 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
staticContext = isNamespaceEnum ? .namespaceEnum(swiftCallName) : .enumName(enumName)
case .protocolBody(_, _):
return nil
case .structBody(let structName, _):
case .structBody(_, let structKey):
if isStatic {
staticContext = .structName(structName)
let structAbiName = exportedStructByName[structKey]?.abiName ?? "unknown"
staticContext = .structName(structAbiName)
} else {
staticContext = nil
}
}

let classNameForABI: String?
switch state {
case .classBody(let className, _):
classNameForABI = className
case .structBody(let structName, _):
classNameForABI = structName
case .classBody(_, let classKey):
classNameForABI = exportedClassByName[classKey]?.abiName
case .structBody(_, let structKey):
classNameForABI = exportedStructByName[structKey]?.abiName
default:
classNameForABI = nil
}
Expand Down Expand Up @@ -1179,7 +1181,7 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
guard let jsAttribute = node.attributes.firstJSAttribute else { return .skipChildren }

switch state {
case .classBody(let className, let classKey):
case .classBody(_, let classKey):
if extractNamespace(from: jsAttribute) != nil {
diagnose(
node: jsAttribute,
Expand All @@ -1194,14 +1196,15 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
return .skipChildren
}

let classAbiName = exportedClassByName[classKey]?.abiName ?? "unknown"
let constructor = ExportedConstructor(
abiName: "bjs_\(className)_init",
abiName: "bjs_\(classAbiName)_init",
parameters: parameters,
effects: effects
)
exportedClassByName[classKey]?.constructor = constructor

case .structBody(let structName, let structKey):
case .structBody(_, let structKey):
if extractNamespace(from: jsAttribute) != nil {
diagnose(
node: jsAttribute,
Expand All @@ -1216,8 +1219,9 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
return .skipChildren
}

let structAbiName = exportedStructByName[structKey]?.abiName ?? "unknown"
let constructor = ExportedConstructor(
abiName: "bjs_\(structName)_init",
abiName: "bjs_\(structAbiName)_init",
parameters: parameters,
effects: effects
)
Expand Down Expand Up @@ -1263,8 +1267,13 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
let staticContext: StaticContext?

switch state {
case .classBody(let className, _):
staticContext = isStatic ? .className(className) : nil
case .classBody(_, let classKey):
if isStatic {
let classAbiName = exportedClassByName[classKey]?.abiName ?? "unknown"
staticContext = .className(classAbiName)
} else {
staticContext = nil
}
case .enumBody(let enumName, let enumKey):
if !isStatic {
diagnose(node: node, message: "Only static properties are supported in enums")
Expand All @@ -1280,9 +1289,10 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
return .skipChildren
case .protocolBody(let protocolName, let protocolKey):
return visitProtocolProperty(node: node, protocolName: protocolName, protocolKey: protocolKey)
case .structBody(let structName, _):
case .structBody(_, let structKey):
if isStatic {
staticContext = .structName(structName)
let structAbiName = exportedStructByName[structKey]?.abiName ?? "unknown"
staticContext = .structName(structAbiName)
} else {
diagnose(node: node, message: "@JS var must be static in structs (instance fields don't need @JS)")
return .skipChildren
Expand Down
10 changes: 5 additions & 5 deletions Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -447,15 +447,15 @@ public struct BridgeJSLink {
printer.write("}")
if !allStructs.isEmpty {
for structDef in allStructs {
printer.write("bjs[\"swift_js_struct_lower_\(structDef.name)\"] = function(objectId) {")
printer.write("bjs[\"swift_js_struct_lower_\(structDef.abiName)\"] = function(objectId) {")
printer.indent {
printer.write(
"\(JSGlueVariableScope.reservedStructHelpers).\(structDef.name).lower(\(JSGlueVariableScope.reservedSwift).memory.getObject(objectId));"
)
}
printer.write("}")

printer.write("bjs[\"swift_js_struct_lift_\(structDef.name)\"] = function() {")
printer.write("bjs[\"swift_js_struct_lift_\(structDef.abiName)\"] = function() {")
printer.indent {
printer.write(
"const value = \(JSGlueVariableScope.reservedStructHelpers).\(structDef.name).lift();"
Expand Down Expand Up @@ -1155,7 +1155,7 @@ public struct BridgeJSLink {
wrapperLines.append("}")

for klass in classes.sorted(by: { $0.name < $1.name }) {
let wrapperFunctionName = "bjs_\(klass.name)_wrap"
let wrapperFunctionName = "bjs_\(klass.abiName)_wrap"
let namespacePath = (klass.namespace ?? []).map { ".\($0)" }.joined()
let exportsPath =
namespacePath.isEmpty ? "_exports['\(klass.name)']" : "_exports\(namespacePath).\(klass.name)"
Expand Down Expand Up @@ -1967,7 +1967,7 @@ extension BridgeJSLink {
jsPrinter.write("static __construct(ptr) {")
jsPrinter.indent {
jsPrinter.write(
"return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_\(klass.name)_deinit, \(klass.name).prototype);"
"return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_\(klass.abiName)_deinit, \(klass.name).prototype);"
)
}
jsPrinter.write("}")
Expand Down Expand Up @@ -2069,7 +2069,7 @@ extension BridgeJSLink {
for property in klass.properties {
try renderClassProperty(
property: property,
className: klass.name,
className: klass.abiName,
isStatic: property.isStatic,
jsPrinter: jsPrinter,
dtsPrinter: property.isStatic ? dtsExportEntryPrinter : dtsTypePrinter
Expand Down
22 changes: 19 additions & 3 deletions Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
// This file is shared between BridgeTool and BridgeJSLink

// MARK: - Namespaced Type Protocol

public protocol NamespacedExportedType {
var name: String { get }
var namespace: [String]? { get }
}

extension NamespacedExportedType {
public var abiName: String {
if let namespace = namespace, !namespace.isEmpty {
return (namespace + [name]).joined(separator: "_")
}
return name
}
}

// MARK: - ABI Name Generation

/// Utility for generating consistent ABI names across all exported and imported types
Expand Down Expand Up @@ -412,7 +428,7 @@ public struct StructField: Codable, Equatable, Sendable {
}
}

public struct ExportedStruct: Codable, Equatable, Sendable {
public struct ExportedStruct: Codable, Equatable, Sendable, NamespacedExportedType {
public let name: String
public let swiftCallName: String
public let explicitAccessControl: String?
Expand Down Expand Up @@ -490,7 +506,7 @@ public enum EnumEmitStyle: String, Codable, Sendable {
case tsEnum
}

public struct ExportedEnum: Codable, Equatable, Sendable {
public struct ExportedEnum: Codable, Equatable, Sendable, NamespacedExportedType {
public static let valuesSuffix = "Values"
public static let objectSuffix = "Object"

Expand Down Expand Up @@ -619,7 +635,7 @@ public struct ExportedFunction: Codable, Equatable, Sendable {
}
}

public struct ExportedClass: Codable {
public struct ExportedClass: Codable, NamespacedExportedType {
public var name: String
public var swiftCallName: String
public var explicitAccessControl: String?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ enum Internal {
}
}

@JS enum Formatting {
@JS class Converter {
@JS init() {}

@JS func format(value: Int) -> String {
return "formatted_\(value)"
}
}
}

@JS(namespace: "Services.Graph")
enum GraphOperations {
@JS static func createGraph(rootId: Int) -> Int {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"classes" : [
{
"constructor" : {
"abiName" : "bjs_Converter_init",
"abiName" : "bjs_Utils_Converter_init",
"effects" : {
"isAsync" : false,
"isStatic" : false,
Expand All @@ -15,7 +15,7 @@
},
"methods" : [
{
"abiName" : "bjs_Converter_toString",
"abiName" : "bjs_Utils_Converter_toString",
"effects" : {
"isAsync" : false,
"isStatic" : false,
Expand Down Expand Up @@ -66,7 +66,7 @@
},
{
"constructor" : {
"abiName" : "bjs_HTTPServer_init",
"abiName" : "bjs_Networking_API_HTTPServer_init",
"effects" : {
"isAsync" : false,
"isStatic" : false,
Expand All @@ -78,7 +78,7 @@
},
"methods" : [
{
"abiName" : "bjs_HTTPServer_call",
"abiName" : "bjs_Networking_API_HTTPServer_call",
"effects" : {
"isAsync" : false,
"isStatic" : false,
Expand Down Expand Up @@ -119,7 +119,7 @@
},
{
"constructor" : {
"abiName" : "bjs_TestServer_init",
"abiName" : "bjs_Networking_APIV2_Internal_TestServer_init",
"effects" : {
"isAsync" : false,
"isStatic" : false,
Expand All @@ -131,7 +131,7 @@
},
"methods" : [
{
"abiName" : "bjs_TestServer_call",
"abiName" : "bjs_Networking_APIV2_Internal_TestServer_call",
"effects" : {
"isAsync" : false,
"isStatic" : false,
Expand Down Expand Up @@ -171,6 +171,57 @@

],
"swiftCallName" : "Internal.TestServer"
},
{
"constructor" : {
"abiName" : "bjs_Formatting_Converter_init",
"effects" : {
"isAsync" : false,
"isStatic" : false,
"isThrows" : false
},
"parameters" : [

]
},
"methods" : [
{
"abiName" : "bjs_Formatting_Converter_format",
"effects" : {
"isAsync" : false,
"isStatic" : false,
"isThrows" : false
},
"name" : "format",
"namespace" : [
"Formatting"
],
"parameters" : [
{
"label" : "value",
"name" : "value",
"type" : {
"int" : {

}
}
}
],
"returnType" : {
"string" : {

}
}
}
],
"name" : "Converter",
"namespace" : [
"Formatting"
],
"properties" : [

],
"swiftCallName" : "Formatting.Converter"
}
],
"enums" : [
Expand Down Expand Up @@ -417,6 +468,21 @@
{
"cases" : [

],
"emitStyle" : "const",
"name" : "Formatting",
"staticMethods" : [

],
"staticProperties" : [

],
"swiftCallName" : "Formatting",
"tsFullPath" : "Formatting"
},
{
"cases" : [

],
"emitStyle" : "const",
"name" : "GraphOperations",
Expand Down
Loading