Skip to content

Commit 777848d

Browse files
authored
Merge pull request #815 from PassiveLogic/kr/protocol-refinement-upstream
BridgeJS: Support protocol refinement and constrained imports
2 parents 53e8cc1 + edca6f9 commit 777848d

22 files changed

Lines changed: 1933 additions & 260 deletions

File tree

‎Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift‎

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,7 +1425,7 @@ struct ProtocolCodegen {
14251425
for method in proto.methods {
14261426
let builder = try ImportTS.CallJSEmission(
14271427
moduleName: moduleName,
1428-
abiName: "_extern_\(method.name)",
1428+
abiName: method.abiName,
14291429
effects: method.effects,
14301430
returnType: method.returnType,
14311431
context: .exportSwift
@@ -1450,7 +1450,7 @@ struct ProtocolCodegen {
14501450
printer: externDeclPrinter,
14511451
moduleName: moduleName,
14521452
abiName: method.abiName,
1453-
functionName: "_extern_\(method.name)",
1453+
functionName: method.abiName,
14541454
abiParameters: builder.abiParameterSignatures,
14551455
returnType: builder.abiReturnType
14561456
)
@@ -1478,32 +1478,34 @@ struct ProtocolCodegen {
14781478
externDecls.append(contentsOf: propertyExternDecls)
14791479
}
14801480

1481-
let structDeclPrinter = CodeFragmentPrinter()
1482-
structDeclPrinter.write("struct \(wrapperName): \(protocolName), _BridgedSwiftProtocolWrapper {")
1483-
structDeclPrinter.indent {
1484-
structDeclPrinter.write("let jsObject: JSObject")
1485-
structDeclPrinter.nextLine()
1486-
1487-
for methodDecl in methodDecls {
1488-
structDeclPrinter.write(lines: methodDecl.lines)
1489-
structDeclPrinter.nextLine()
1490-
}
1491-
1492-
for decl in propertyDecls {
1493-
structDeclPrinter.write(lines: decl.lines)
1494-
structDeclPrinter.nextLine()
1481+
var decls: [DeclSyntax] = []
1482+
if !methodDecls.isEmpty || !propertyDecls.isEmpty {
1483+
let extensionPrinter = CodeFragmentPrinter()
1484+
extensionPrinter.write("extension \(protocolName) where Self: _BridgedSwiftProtocolWrapper {")
1485+
extensionPrinter.indent {
1486+
var first = true
1487+
for decl in methodDecls + propertyDecls {
1488+
if !first { extensionPrinter.nextLine() }
1489+
first = false
1490+
extensionPrinter.write(lines: decl.lines)
1491+
}
14951492
}
1496-
structDeclPrinter.write(
1497-
multilineString: """
1498-
static func bridgeJSLiftParameter(_ value: Int32) -> Self {
1499-
return \(wrapperName)(jsObject: JSObject(id: UInt32(bitPattern: value)))
1500-
}
1501-
"""
1502-
)
1493+
extensionPrinter.write("}")
1494+
decls.append("\(raw: extensionPrinter.lines.joined(separator: "\n"))")
15031495
}
1504-
structDeclPrinter.write("}")
15051496

1506-
return ["\(raw: structDeclPrinter.lines.joined(separator: "\n"))"] + externDecls
1497+
decls.append(
1498+
"""
1499+
struct \(raw: wrapperName): \(raw: protocolName), _BridgedSwiftProtocolWrapper {
1500+
let jsObject: JSObject
1501+
1502+
static func bridgeJSLiftParameter(_ value: Int32) -> Self {
1503+
return \(raw: wrapperName)(jsObject: JSObject(id: UInt32(bitPattern: value)))
1504+
}
1505+
}
1506+
"""
1507+
)
1508+
return decls + externDecls
15071509
}
15081510

15091511
private func renderProtocolProperty(

‎Plugins/BridgeJS/Sources/BridgeJSCore/ExternalModuleIndex.swift‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ public struct ExternalModuleIndex {
77
public struct ExternalType: Equatable {
88
public let moduleName: String
99
public let bridgeType: BridgeType
10+
public var isGenericBridgeableProtocol = false
1011
}
1112

1213
public enum LookupResult: Equatable {
@@ -31,8 +32,12 @@ public struct ExternalModuleIndex {
3132
guard let exported = skeleton.exported else { continue }
3233
var moduleEntries = entriesByModule[moduleName] ?? [:]
3334

34-
func register(dotPath: String, bridgeType: BridgeType) {
35-
let externalType = ExternalType(moduleName: moduleName, bridgeType: bridgeType)
35+
func register(dotPath: String, bridgeType: BridgeType, isGenericBridgeableProtocol: Bool = false) {
36+
let externalType = ExternalType(
37+
moduleName: moduleName,
38+
bridgeType: bridgeType,
39+
isGenericBridgeableProtocol: isGenericBridgeableProtocol
40+
)
3641
if moduleEntries[dotPath] == nil {
3742
moduleEntries[dotPath] = externalType
3843
entriesByDotPath[dotPath, default: []].append(externalType)
@@ -61,7 +66,11 @@ public struct ExternalModuleIndex {
6166
register(dotPath: enumDef.swiftCallName, bridgeType: bridgeType)
6267
}
6368
for proto in exported.protocols {
64-
register(dotPath: proto.name, bridgeType: .swiftProtocol(proto.name))
69+
register(
70+
dotPath: proto.name,
71+
bridgeType: .swiftProtocol(proto.name),
72+
isGenericBridgeableProtocol: proto.isGenericBridgeable == true
73+
)
6574
}
6675
for alias in exported.aliases {
6776
register(

‎Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift‎

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ public struct ImportTS {
381381
parameters: [Parameter],
382382
returnType: BridgeType,
383383
effects: Effects,
384-
genericParameters: [String] = []
384+
genericParameters: [GenericParameter] = []
385385
) -> DeclSyntax {
386386
let printer = CodeFragmentPrinter()
387387
let signature = SwiftSignatureBuilder.buildFunctionSignature(
@@ -393,7 +393,13 @@ public struct ImportTS {
393393
let genericClause =
394394
genericParameters.isEmpty
395395
? ""
396-
: "<" + genericParameters.map { "\($0): BridgedSwiftGenericBridgeable" }.joined(separator: ", ")
396+
: "<"
397+
+ genericParameters.map { genericParameter in
398+
let constraints =
399+
["BridgedSwiftGenericBridgeable"]
400+
+ (genericParameter.swiftConstraints ?? genericParameter.constraints)
401+
return "\(genericParameter.name): \(constraints.joined(separator: " & "))"
402+
}.joined(separator: ", ")
397403
+ ">"
398404
printer.write("func \(name.backtickIfNeeded())\(genericClause)\(signature) {")
399405
printer.indent {
@@ -465,7 +471,7 @@ public struct ImportTS {
465471
parameters: function.parameters,
466472
returnType: function.returnType,
467473
effects: function.effects,
468-
genericParameters: function.genericParameterNames
474+
genericParameters: function.genericParameters ?? []
469475
)
470476
.with(\.leadingTrivia, Self.renderDocumentation(documentation: function.documentation))
471477
]
@@ -496,7 +502,7 @@ public struct ImportTS {
496502
parameters: [selfParameter] + method.parameters,
497503
returnType: method.returnType,
498504
effects: method.effects,
499-
genericParameters: method.genericParameterNames
505+
genericParameters: method.genericParameters ?? []
500506
)
501507
]
502508
}
@@ -522,7 +528,7 @@ public struct ImportTS {
522528
parameters: method.parameters,
523529
returnType: method.returnType,
524530
effects: method.effects,
525-
genericParameters: method.genericParameterNames
531+
genericParameters: method.genericParameters ?? []
526532
)
527533
]
528534
}
@@ -548,7 +554,7 @@ public struct ImportTS {
548554
parameters: constructor.parameters,
549555
returnType: .jsObject(nil),
550556
effects: effects,
551-
genericParameters: constructor.genericParameterNames
557+
genericParameters: constructor.genericParameters ?? []
552558
)
553559
]
554560
}

0 commit comments

Comments
 (0)