Skip to content

Commit 0d0af8b

Browse files
committed
add support for failable initializers
1 parent 9b53e69 commit 0d0af8b

File tree

5 files changed

+97
-17
lines changed

5 files changed

+97
-17
lines changed

Samples/JExtractJNISampleApp/Sources/MySwiftLibrary/Vehicle.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,39 @@ public enum Vehicle {
1616
case bicycle
1717
case car(String)
1818
case motorbike(String, horsePower: Int64)
19+
20+
public init?(name: String) {
21+
switch name {
22+
case "bicycle": self = .bicycle
23+
case "car": self = .car("Unknown")
24+
case "motorbike": self = .motorbike("Unknown", horsePower: 0)
25+
default: return nil
26+
}
27+
}
28+
29+
public var name: String {
30+
switch self {
31+
case .bicycle: "bicycle"
32+
case .car: "car"
33+
case .motorbike: "motorbike"
34+
}
35+
}
36+
37+
public func isFasterThan(other: Vehicle) -> Bool {
38+
switch (self, other) {
39+
case (.bicycle, .bicycle), (.bicycle, .car), (.bicycle, .motorbike): false
40+
case (.car, .bicycle): true
41+
case (.car, .motorbike), (.car, .car): false
42+
case (.motorbike, .bicycle), (.motorbike, .car): true
43+
case (.motorbike, .motorbike): false
44+
}
45+
}
46+
47+
public mutating func upgrade() {
48+
switch self {
49+
case .bicycle: self = .car("Unknown")
50+
case .car: self = .motorbike("Unknown", horsePower: 0)
51+
case .motorbike: break
52+
}
53+
}
1954
}

Samples/JExtractJNISampleApp/src/test/java/com/example/swift/VehicleTest.java

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
import org.junit.jupiter.api.Test;
1818
import org.swift.swiftkit.core.ConfinedSwiftMemorySession;
1919

20-
import static org.junit.jupiter.api.Assertions.assertEquals;
21-
import static org.junit.jupiter.api.Assertions.assertNotNull;
20+
import java.util.Optional;
21+
22+
import static org.junit.jupiter.api.Assertions.*;
2223

2324
public class VehicleTest {
2425
@Test
@@ -44,4 +45,44 @@ void motorbike() {
4445
assertNotNull(vehicle);
4546
}
4647
}
48+
49+
@Test
50+
void initName() {
51+
try (var arena = new ConfinedSwiftMemorySession()) {
52+
assertFalse(Vehicle.init("bus", arena).isPresent());
53+
Optional<Vehicle> vehicle = Vehicle.init("car", arena);
54+
assertTrue(vehicle.isPresent());
55+
assertNotNull(vehicle.get());
56+
}
57+
}
58+
59+
@Test
60+
void nameProperty() {
61+
try (var arena = new ConfinedSwiftMemorySession()) {
62+
Vehicle vehicle = Vehicle.bicycle(arena);
63+
assertEquals("bicycle", vehicle.getName());
64+
}
65+
}
66+
67+
@Test
68+
void isFasterThan() {
69+
try (var arena = new ConfinedSwiftMemorySession()) {
70+
Vehicle bicycle = Vehicle.bicycle(arena);
71+
Vehicle car = Vehicle.car("Porsche 911", arena);
72+
assertFalse(bicycle.isFasterThan(car));
73+
assertTrue(car.isFasterThan(bicycle));
74+
}
75+
}
76+
77+
@Test
78+
void upgrade() {
79+
try (var arena = new ConfinedSwiftMemorySession()) {
80+
Vehicle vehicle = Vehicle.bicycle(arena);
81+
assertEquals("bicycle", vehicle.getName());
82+
vehicle.upgrade();
83+
assertEquals("car", vehicle.getName());
84+
vehicle.upgrade();
85+
assertEquals("motorbike", vehicle.getName());
86+
}
87+
}
4788
}

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,11 @@ extension JNISwift2JavaGenerator {
196196
// TODO: Move this to seperate file +Enum?
197197
printEnumDiscriminator(&printer, decl)
198198
printer.println()
199+
printEnumCaseInterface(&printer, decl)
200+
printer.println()
199201
printEnumStaticInitializers(&printer, decl)
202+
printer.println()
203+
printEnumCases(&printer, decl)
200204
}
201205

202206
private func printEnumDiscriminator(_ printer: inout CodePrinter, _ decl: ImportedNominalType) {
@@ -207,12 +211,24 @@ extension JNISwift2JavaGenerator {
207211
}
208212
}
209213

214+
private func printEnumCaseInterface(_ printer: inout CodePrinter, _ decl: ImportedNominalType) {
215+
// printer.print("public sealed interface Case {}")
216+
}
217+
210218
private func printEnumStaticInitializers(_ printer: inout CodePrinter, _ decl: ImportedNominalType) {
211219
for enumCase in decl.cases {
212220
printFunctionDowncallMethods(&printer, enumCase.caseFunction)
213221
}
214222
}
215223

224+
private func printEnumCases(_ printer: inout CodePrinter, _ decl: ImportedNominalType) {
225+
// for enumCase in decl.cases {
226+
// printer.printBraceBlock("public static final \(enumCase.name.firstCharacterUppercased) implements Case") { printer in
227+
//
228+
// }
229+
// }
230+
}
231+
216232
private func printFunctionDowncallMethods(
217233
_ printer: inout CodePrinter,
218234
_ decl: ImportedFunc

Sources/JExtractSwiftLib/Swift2JavaVisitor.swift

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -276,15 +276,6 @@ extension DeclSyntaxProtocol where Self: WithModifiersSyntax & WithAttributesSyn
276276
return false
277277
}
278278

279-
if let node = self.as(InitializerDeclSyntax.self) {
280-
let isFailable = node.optionalMark != nil
281-
282-
if isFailable {
283-
log.warning("Skip import '\(self.qualifiedNameForDebug)': failable initializer")
284-
return false
285-
}
286-
}
287-
288279
return true
289280
}
290281
}

Sources/JExtractSwiftLib/SwiftTypes/SwiftFunctionSignature.swift

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,6 @@ extension SwiftFunctionSignature {
7171
throw SwiftFunctionTranslationError.missingEnclosingType(node)
7272
}
7373

74-
// We do not yet support failable initializers.
75-
if node.optionalMark != nil {
76-
throw SwiftFunctionTranslationError.failableInitializer(node)
77-
}
78-
7974
let (genericParams, genericRequirements) = try Self.translateGenericParameters(
8075
parameterClause: node.genericParameterClause,
8176
whereClause: node.genericWhereClause,
@@ -86,10 +81,12 @@ extension SwiftFunctionSignature {
8681
lookupContext: lookupContext
8782
)
8883

84+
let type = node.optionalMark != nil ? .optional(enclosingType) : enclosingType
85+
8986
self.init(
9087
selfParameter: .initializer(enclosingType),
9188
parameters: parameters,
92-
result: SwiftResult(convention: .direct, type: enclosingType),
89+
result: SwiftResult(convention: .direct, type: type),
9390
effectSpecifiers: effectSpecifiers,
9491
genericParameters: genericParams,
9592
genericRequirements: genericRequirements

0 commit comments

Comments
 (0)