Skip to content

Commit 5aa9fad

Browse files
committed
cleanup existential type rendering
1 parent 77480ba commit 5aa9fad

3 files changed

Lines changed: 36 additions & 14 deletions

File tree

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+NativeTranslation.swift

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ extension JNISwift2JavaGenerator {
10821082
indirect case extractSwiftProtocolValue(
10831083
NativeSwiftConversionStep,
10841084
typeMetadataVariableName: NativeSwiftConversionStep,
1085-
protocolNames: [String]
1085+
protocolTypes: [SwiftNominalType]
10861086
)
10871087

10881088
/// Extracts a swift type at a pointer given by a long.
@@ -1228,12 +1228,10 @@ extension JNISwift2JavaGenerator {
12281228
let protocolTypes,
12291229
let allowsJavaImplementations
12301230
):
1231-
let protocolNames = protocolTypes.map { $0.nominalTypeDecl.qualifiedName }
1232-
12331231
let inner = inner.render(&printer, placeholder)
12341232
let variableName = "\(inner)swiftObject$"
1235-
let compositeProtocolName = "(\(protocolNames.joined(separator: " & ")))"
1236-
printer.print("let \(variableName): \(compositeProtocolName)")
1233+
let existentialType = SwiftKitPrinting.renderExistentialType(protocolTypes)
1234+
printer.print("let \(variableName): \(existentialType)")
12371235

12381236
func printStandardJExtractBlock(_ printer: inout CodePrinter) {
12391237
let pointerVariableName = "\(inner)pointer$"
@@ -1247,7 +1245,7 @@ extension JNISwift2JavaGenerator {
12471245
let existentialName = NativeSwiftConversionStep.extractSwiftProtocolValue(
12481246
.constant(pointerVariableName),
12491247
typeMetadataVariableName: .constant(typeMetadataVariableName),
1250-
protocolNames: protocolNames
1248+
protocolTypes: protocolTypes
12511249
).render(&printer, placeholder)
12521250

12531251
printer.print("\(variableName) = \(existentialName)")
@@ -1276,12 +1274,12 @@ extension JNISwift2JavaGenerator {
12761274

12771275
return variableName
12781276

1279-
case .extractSwiftProtocolValue(let inner, let typeMetadataVariableName, let protocolNames):
1277+
case .extractSwiftProtocolValue(let inner, let typeMetadataVariableName, let protocolTypes):
12801278
let inner = inner.render(&printer, placeholder)
12811279
let typeMetadataVariableName = typeMetadataVariableName.render(&printer, placeholder)
12821280
let existentialName = "\(inner)Existential$"
12831281

1284-
let compositeProtocolName = "(\(protocolNames.joined(separator: " & ")))"
1282+
let existentialType = SwiftKitPrinting.renderExistentialType(protocolTypes)
12851283

12861284
// TODO: Remove the _openExistential when we decide to only support language mode v6+
12871285
printer.print(
@@ -1294,10 +1292,10 @@ extension JNISwift2JavaGenerator {
12941292
fatalError("\(inner) memory address was null")
12951293
}
12961294
#if hasFeature(ImplicitOpenExistentials)
1297-
let \(existentialName) = \(inner)RawPointer$.load(as: \(inner)DynamicType$) as! any \(compositeProtocolName)
1295+
let \(existentialName) = \(inner)RawPointer$.load(as: \(inner)DynamicType$) as! \(existentialType)
12981296
#else
1299-
func \(inner)DoLoad<Ty>(_ ty: Ty.Type) -> any \(compositeProtocolName) {
1300-
\(inner)RawPointer$.load(as: ty) as! any \(compositeProtocolName)
1297+
func \(inner)DoLoad<Ty>(_ ty: Ty.Type) -> \(existentialType) {
1298+
\(inner)RawPointer$.load(as: ty) as! \(existentialType)
13011299
}
13021300
let \(existentialName) = _openExistential(\(inner)DynamicType$, do: \(inner)DoLoad)
13031301
#endif

Sources/JExtractSwiftLib/SwiftKit+Printing.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,23 @@ package struct SwiftKitPrinting {
2626
SwiftRuntime.swiftjava.getType("\(module)", "\(nominal.swiftNominal.qualifiedName)")
2727
"""
2828
}
29+
30+
/// Render a parenthesized existential type constraint from nominal protocol types
31+
///
32+
/// For a single protocol: `(any DataProtocol)`
33+
/// For multiple protocols: `(any (DataProtocol & Sendable))`
34+
static func renderExistentialType(_ protocolTypes: [SwiftNominalType]) -> String {
35+
let compositeType: SwiftType
36+
if protocolTypes.count == 1 {
37+
compositeType = .nominal(protocolTypes[0])
38+
} else {
39+
compositeType = .composite(protocolTypes.map { .nominal($0) })
40+
}
41+
return "(\(SwiftType.existential(compositeType)))"
42+
}
2943
}
3044

31-
// ==== ------------------------------------------------------------------------
45+
// ==== -----------------------------------------------------------------------
3246
// Helpers to form names of "well known" SwiftKit generated functions
3347

3448
extension SwiftKitPrinting {

Sources/JExtractSwiftLib/SwiftTypes/SwiftType.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,19 @@ extension SwiftType: CustomStringConvertible {
167167
case .tuple(let elements):
168168
return "(\(elements.map(\.description).joined(separator: ", ")))"
169169
case .existential(let constraintType):
170-
return "any \(constraintType)"
170+
switch constraintType {
171+
case .composite:
172+
return "any (\(constraintType))"
173+
default:
174+
return "any \(constraintType)"
175+
}
171176
case .opaque(let constraintType):
172-
return "some \(constraintType)"
177+
switch constraintType {
178+
case .composite:
179+
return "some (\(constraintType))"
180+
default:
181+
return "some \(constraintType)"
182+
}
173183
case .composite(let types):
174184
return types.map(\.description).joined(separator: " & ")
175185
}

0 commit comments

Comments
 (0)