Skip to content

Commit 4b045b2

Browse files
committed
Java2Swift: Don't translate Java interfaces into Swift classes
Keep interfaces as structs for now. Their future is yet unwritten.
1 parent c3337b6 commit 4b045b2

File tree

3 files changed

+42
-10
lines changed

3 files changed

+42
-10
lines changed

Sources/Java2SwiftLib/JavaClassTranslator.swift

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ struct JavaClassTranslator {
2626
/// The Java class (or interface) being translated.
2727
let javaClass: JavaClass<JavaObject>
2828

29+
/// Whether to translate this Java class into a Swift class.
30+
///
31+
/// This will be false for Java interfaces.
32+
let translateAsClass: Bool
33+
2934
/// The type parameters to the Java class or interface.
3035
let javaTypeParameters: [TypeVariable<JavaClass<JavaObject>>]
3136

@@ -107,6 +112,7 @@ struct JavaClassTranslator {
107112
let fullName = javaClass.getName()
108113
self.javaClass = javaClass
109114
self.translator = translator
115+
self.translateAsClass = translator.translateAsClass && !javaClass.isInterface()
110116
self.swiftTypeName = try translator.getSwiftTypeNameFromJavaClassName(
111117
fullName,
112118
preferValueTypes: false,
@@ -175,7 +181,7 @@ struct JavaClassTranslator {
175181
}
176182

177183
// Gather methods.
178-
let methods = translator.translateAsClass
184+
let methods = translateAsClass
179185
? javaClass.getDeclaredMethods()
180186
: javaClass.getMethods()
181187
for method in methods {
@@ -231,7 +237,7 @@ extension JavaClassTranslator {
231237
}
232238

233239
// Don't include inherited fields when translating to a class.
234-
if translator.translateAsClass &&
240+
if translateAsClass &&
235241
!field.getDeclaringClass()!.equals(javaClass.as(JavaObject.self)!) {
236242
return
237243
}
@@ -315,7 +321,7 @@ extension JavaClassTranslator {
315321
// formulation).
316322
let extends: String
317323
let inheritanceClause: String
318-
if translator.translateAsClass {
324+
if translateAsClass {
319325
extends = ""
320326
inheritanceClause = swiftSuperclass.map { ": \($0)" } ?? ""
321327
} else {
@@ -334,7 +340,7 @@ extension JavaClassTranslator {
334340

335341
// Emit the struct declaration describing the java class.
336342
let classOrInterface: String = isInterface ? "JavaInterface" : "JavaClass";
337-
let introducer = translator.translateAsClass ? "open class" : "public struct"
343+
let introducer = translateAsClass ? "open class" : "public struct"
338344
var classDecl: DeclSyntax =
339345
"""
340346
@\(raw: classOrInterface)(\(literal: javaClass.getName())\(raw: extends)\(raw: interfacesStr))
@@ -485,7 +491,7 @@ extension JavaClassTranslator {
485491
let parametersStr = parameters.map { $0.description }.joined(separator: ", ")
486492
let throwsStr = javaConstructor.throwsCheckedException ? "throws" : ""
487493
let accessModifier = javaConstructor.isPublic ? "public " : ""
488-
let convenienceModifier = translator.translateAsClass ? "convenience " : ""
494+
let convenienceModifier = translateAsClass ? "convenience " : ""
489495
return """
490496
@JavaMethod
491497
\(raw: accessModifier)\(raw: convenienceModifier)init(\(raw: parametersStr))\(raw: throwsStr)
@@ -523,10 +529,9 @@ extension JavaClassTranslator {
523529
? ""
524530
: javaMethod.isStatic ? "@JavaStaticMethod\n" : "@JavaMethod\n";
525531
let accessModifier = implementedInSwift ? ""
526-
: (javaMethod.isStatic || !translator.translateAsClass) ? "public "
532+
: (javaMethod.isStatic || !translateAsClass) ? "public "
527533
: "open "
528-
let overrideOpt = (translator.translateAsClass &&
529-
!javaMethod.isStatic && isOverride(javaMethod))
534+
let overrideOpt = (translateAsClass && !javaMethod.isStatic && isOverride(javaMethod))
530535
? "override "
531536
: ""
532537
return """
@@ -577,7 +582,7 @@ extension JavaClassTranslator {
577582
}
578583
"""
579584

580-
let convenienceModifier = translator.translateAsClass ? "convenience " : ""
585+
let convenienceModifier = translateAsClass ? "convenience " : ""
581586
let initSyntax: DeclSyntax = """
582587
public \(raw: convenienceModifier)init(_ enumValue: \(raw: name), environment: JNIEnvironment? = nil) {
583588
let _environment = if let environment {
@@ -591,7 +596,7 @@ extension JavaClassTranslator {
591596
return """
592597
case .\($0.getName()):
593598
if let \($0.getName()) = classObj.\($0.getName()) {
594-
\(translator.translateAsClass
599+
\(translateAsClass
595600
? "self.init(javaHolder: \($0.getName()).javaHolder)"
596601
: "self = \($0.getName())")
597602
} else {

Sources/Java2SwiftLib/JavaTranslator.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ package class JavaTranslator {
2626
let swiftModuleName: String
2727

2828
let environment: JNIEnvironment
29+
30+
/// Whether to translate Java classes into classes (rather than structs).
2931
let translateAsClass: Bool
32+
3033
let format: BasicFormat
3134

3235
/// A mapping from the name of each known Java class to the corresponding

Tests/Java2SwiftTests/Java2SwiftTests.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,30 @@ class Java2SwiftTests: XCTestCase {
456456
]
457457
)
458458
}
459+
460+
func testJavaInterfaceAsClassNOT() throws {
461+
try assertTranslatedClass(
462+
MyJavaIntFunction<JavaObject>.self,
463+
swiftTypeName: "MyJavaIntFunction",
464+
asClass: true,
465+
translatedClasses: [
466+
"java.lang.Object" : ("JavaObject", "JavaKit"),
467+
"java.util.function.IntFunction": ("MyJavaIntFunction", nil),
468+
],
469+
expectedChunks: [
470+
"import JavaKit",
471+
"""
472+
@JavaInterface("java.util.function.IntFunction")
473+
public struct MyJavaIntFunction<R: AnyJavaObject> {
474+
""",
475+
"""
476+
@JavaMethod
477+
public func apply(_ arg0: Int32) -> JavaObject!
478+
""",
479+
]
480+
)
481+
482+
}
459483
}
460484

461485
@JavaClass("java.lang.ClassLoader")

0 commit comments

Comments
 (0)