Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
//
//===----------------------------------------------------------------------===//

import JavaKit

public func optionalBool(input: Optional<Bool>) -> Bool? {
return input
}
Expand Down Expand Up @@ -52,6 +54,14 @@ public func optionalClass(input: Optional<MySwiftClass>) -> MySwiftClass? {
return input
}

public func optionalJavaKitLong(input: Optional<JavaLong>) -> Int64? {
if let input {
return input.longValue()
} else {
return nil
}
}

public func multipleOptionals(
input1: Optional<Int8>,
input2: Optional<Int16>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ void optionalClass() {
}
}

@Test
void optionalJavaKitLong() {
assertEquals(OptionalLong.empty(), MySwiftLibrary.optionalJavaKitLong(Optional.empty()));
assertEquals(OptionalLong.of(99L), MySwiftLibrary.optionalJavaKitLong(Optional.of(99L)));
}

@Test
void multipleOptionals() {
try (var arena = new ConfinedSwiftMemorySession()) {
Expand Down
25 changes: 25 additions & 0 deletions Sources/JExtractSwiftLib/Convenience/JavaType+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,29 @@ extension JavaType {
case .void: nil
}
}

var jniCallMethodAName: String {
switch self {
case .boolean: "CallBooleanMethodA"
case .byte: "CallByteMethodA"
case .char: "CallCharMethodA"
case .short: "CallShortMethodA"
case .int: "CallIntMethodA"
case .long: "CallLongMethodA"
case .float: "CallFloatMethodA"
case .double: "CallDoubleMethodA"
case .void: "CallVoidMethodA"
default: "CallObjectMethodA"
}
}

/// Returns whether this type returns `JavaValue` from JavaKit
var implementsJavaValue: Bool {
return switch self {
case .boolean, .byte, .char, .short, .int, .long, .float, .double, .void, .javaLangString:
true
default:
false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,23 @@ extension JNISwift2JavaGenerator {
)
}

guard !nominalType.isJavaKitWrapper else {
throw JavaTranslationError.unsupportedSwiftType(swiftType)
if nominalType.isJavaKitWrapper {
guard let javaType = nominalTypeName.parseJavaClassFromJavaKitName(in: self.javaClassLookupTable) else {
throw JavaTranslationError.wrappedJavaClassTranslationNotProvided(swiftType)
}

return TranslatedParameter(
parameter: JavaParameter(
name: parameterName,
type: .class(package: nil, name: "Optional<\(javaType)>"),
annotations: parameterAnnotations
),
conversion: .method(
.placeholder,
function: "orElse",
arguments: [.constant("null")]
)
)
}

// Assume JExtract imported class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,14 @@ extension JNISwift2JavaGenerator {
parameters: [
JavaParameter(name: parameterName, type: javaType)
],
conversion: .initializeJavaKitWrapper(wrapperName: nominalTypeName)
conversion: .initializeJavaKitWrapper(
.unwrapOptional(
.placeholder,
name: parameterName,
fatalErrorMessage: "\(parameterName) was null in call to \\(#function), but Swift requires non-optional!"
),
wrapperName: nominalTypeName
)
)
}

Expand Down Expand Up @@ -170,6 +177,8 @@ extension JNISwift2JavaGenerator {

switch swiftType {
case .nominal(let nominalType):
let nominalTypeName = nominalType.nominalTypeDecl.name

if let knownType = nominalType.nominalTypeDecl.knownTypeKind {
guard let javaType = JNIJavaTypeTranslator.translate(knownType: knownType, config: self.config),
javaType.implementsJavaValue else {
Expand All @@ -189,8 +198,17 @@ extension JNISwift2JavaGenerator {
)
}

guard !nominalType.isJavaKitWrapper else {
throw JavaTranslationError.unsupportedSwiftType(swiftType)
if nominalType.isJavaKitWrapper {
guard let javaType = nominalTypeName.parseJavaClassFromJavaKitName(in: self.javaClassLookupTable) else {
throw JavaTranslationError.wrappedJavaClassTranslationNotProvided(swiftType)
}

return NativeParameter(
parameters: [
JavaParameter(name: parameterName, type: javaType)
],
conversion: .optionalMap(.initializeJavaKitWrapper(.placeholder, wrapperName: nominalTypeName))
)
}

// Assume JExtract wrapped class
Expand Down Expand Up @@ -456,7 +474,7 @@ extension JNISwift2JavaGenerator {

indirect case closureLowering(parameters: [NativeParameter], result: NativeResult)

case initializeJavaKitWrapper(wrapperName: String)
indirect case initializeJavaKitWrapper(NativeSwiftConversionStep, wrapperName: String)

indirect case optionalLowering(NativeSwiftConversionStep, discriminatorName: String, valueName: String)

Expand All @@ -470,6 +488,10 @@ extension JNISwift2JavaGenerator {

indirect case member(NativeSwiftConversionStep, member: String)

indirect case optionalMap(NativeSwiftConversionStep)

indirect case unwrapOptional(NativeSwiftConversionStep, name: String, fatalErrorMessage: String)

/// Returns the conversion string applied to the placeholder.
func render(_ printer: inout CodePrinter, _ placeholder: String) -> String {
// NOTE: 'printer' is used if the conversion wants to cause side-effects.
Expand Down Expand Up @@ -558,7 +580,7 @@ extension JNISwift2JavaGenerator {
"""
)

let upcall = "environment!.interface.\(nativeResult.javaType.jniType.callMethodAName)(environment, \(placeholder), methodID$, arguments$)"
let upcall = "environment!.interface.\(nativeResult.javaType.jniCallMethodAName)(environment, \(placeholder), methodID$, arguments$)"
let result = nativeResult.conversion.render(&printer, upcall)

if nativeResult.javaType.isVoid {
Expand All @@ -572,8 +594,9 @@ extension JNISwift2JavaGenerator {

return printer.finalize()

case .initializeJavaKitWrapper(let wrapperName):
return "\(wrapperName)(javaThis: \(placeholder), environment: environment!)"
case .initializeJavaKitWrapper(let inner, let wrapperName):
let inner = inner.render(&printer, placeholder)
return "\(wrapperName)(javaThis: \(inner), environment: environment!)"

case .optionalLowering(let valueConversion, let discriminatorName, let valueName):
let value = valueConversion.render(&printer, valueName)
Expand Down Expand Up @@ -637,6 +660,26 @@ extension JNISwift2JavaGenerator {
case .member(let inner, let member):
let inner = inner.render(&printer, placeholder)
return "\(inner).\(member)"

case .optionalMap(let inner):
var printer = CodePrinter()
printer.printBraceBlock("\(placeholder).map") { printer in
let inner = inner.render(&printer, "$0")
printer.print("return \(inner)")
}
return printer.finalize()

case .unwrapOptional(let inner, let name, let fatalErrorMessage):
let unwrappedName = "\(name)_unwrapped$"
let inner = inner.render(&printer, placeholder)
printer.print(
"""
guard let \(unwrappedName) = \(inner) else {
fatalError("\(fatalErrorMessage)")
}
"""
)
return unwrappedName
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ extension JNISwift2JavaGenerator {
+ jniSignature.escapedJNIIdentifier

let translatedParameters = parameters.map {
"\($0.name): \($0.type.jniType)"
"\($0.name): \($0.type.jniTypeName)"
}

let thunkParameters =
Expand Down
98 changes: 0 additions & 98 deletions Sources/JExtractSwiftLib/JNI/JNIType.swift

This file was deleted.

Loading