Skip to content

Commit b9122bd

Browse files
java2swift: Add Support for Enum Cases (#76)
* Add Support for Enum Cases * Fix building * Remove print * Update enum values to the new setup * Add new initializer from enum case * not throws or optional * Remove unnecessary addition of java.lang.Object mapping --------- Co-authored-by: Doug Gregor <dgregor@apple.com>
1 parent 8b547c3 commit b9122bd

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

Sources/Java2SwiftLib/JavaTranslator.swift

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,16 @@ extension JavaTranslator {
234234

235235
// Fields
236236
var staticFields: [Field] = []
237+
var enumConstants: [Field] = []
237238
members.append(
238239
contentsOf: javaClass.getFields().compactMap {
239240
$0.flatMap { field in
240241
if field.isStatic {
241242
staticFields.append(field)
243+
244+
if field.isEnumConstant() {
245+
enumConstants.append(field)
246+
}
242247
return nil
243248
}
244249

@@ -252,6 +257,13 @@ extension JavaTranslator {
252257
}
253258
)
254259

260+
if !enumConstants.isEmpty {
261+
let enumName = "\(swiftTypeName)Cases"
262+
members.append(
263+
contentsOf: translateToEnumValue(name: enumName, enumFields: enumConstants)
264+
)
265+
}
266+
255267
// Constructors
256268
members.append(
257269
contentsOf: javaClass.getConstructors().compactMap {
@@ -447,6 +459,50 @@ extension JavaTranslator {
447459
"""
448460
}
449461

462+
package func translateToEnumValue(name: String, enumFields: [Field]) -> [DeclSyntax] {
463+
let extensionSyntax: DeclSyntax = """
464+
public enum \(raw: name): Equatable {
465+
\(raw: enumFields.map { "case \($0.getName())" }.joined(separator: "\n"))
466+
}
467+
"""
468+
469+
let mappingSyntax: DeclSyntax = """
470+
public var enumValue: \(raw: name)? {
471+
let classObj = self.javaClass
472+
\(raw: enumFields.map {
473+
// The equals method takes a java object, so we need to cast it here
474+
"""
475+
if self.equals(classObj.\($0.getName())?.as(JavaObject.self)) {
476+
return \(name).\($0.getName())
477+
}
478+
"""
479+
}.joined(separator: " else ")) else {
480+
return nil
481+
}
482+
}
483+
"""
484+
485+
let initSyntax: DeclSyntax = """
486+
public init(_ enumValue: \(raw: name), environment: JNIEnvironment) {
487+
let classObj = try! JavaClass<Self>(in: environment)
488+
switch enumValue {
489+
\(raw: enumFields.map {
490+
return """
491+
case .\($0.getName()):
492+
if let \($0.getName()) = classObj.\($0.getName()) {
493+
self = \($0.getName())
494+
} else {
495+
fatalError("Enum value \($0.getName()) was unexpectedly nil, please re-run Java2Swift on the most updated Java class")
496+
}
497+
"""
498+
}.joined(separator: "\n"))
499+
}
500+
}
501+
"""
502+
503+
return [extensionSyntax, mappingSyntax, initSyntax]
504+
}
505+
450506
// Translate a Java parameter list into Swift parameters.
451507
private func translateParameters(_ parameters: [Parameter?]) throws -> [FunctionParameterSyntax] {
452508
return try parameters.compactMap { javaParameter in

Tests/Java2SwiftTests/Java2SwiftTests.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ var jvm: JavaVirtualMachine {
2424
}
2525
}
2626

27+
@JavaClass("java.time.Month")
28+
public struct JavaMonth {
29+
30+
}
31+
2732
class Java2SwiftTests: XCTestCase {
2833
func testJavaLangObjectMapping() throws {
2934
try assertTranslatedClass(
@@ -47,6 +52,36 @@ class Java2SwiftTests: XCTestCase {
4752
)
4853
}
4954

55+
func testEnum() async throws {
56+
try assertTranslatedClass(
57+
JavaMonth.self,
58+
swiftTypeName: "Month",
59+
expectedChunks: [
60+
"import JavaKit",
61+
"enum MonthCases: Equatable",
62+
"case APRIL",
63+
"public var enumValue: MonthCases?",
64+
"""
65+
} else if self.equals(classObj.APRIL?.as(JavaObject.self)) {
66+
return MonthCases.APRIL
67+
}
68+
""",
69+
"public init(_ enumValue: MonthCases, environment: JNIEnvironment) {",
70+
"""
71+
case .APRIL:
72+
if let APRIL = classObj.APRIL {
73+
self = APRIL
74+
} else {
75+
fatalError("Enum value APRIL was unexpectedly nil, please re-run Java2Swift on the most updated Java class")
76+
}
77+
""",
78+
"""
79+
@JavaStaticField
80+
public var APRIL: Month?
81+
"""
82+
])
83+
}
84+
5085
func testGenericCollections() throws {
5186
try assertTranslatedClass(
5287
MyArrayList<JavaObject>.self,

0 commit comments

Comments
 (0)