Skip to content

Commit 33ed99e

Browse files
committed
Improve Optional handling, and generic get() -> T
1 parent f010c8e commit 33ed99e

File tree

13 files changed

+232
-25
lines changed

13 files changed

+232
-25
lines changed

Samples/JavaKitSampleApp/Package.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,16 @@ let package = Package(
7878
.plugin(name: "SwiftJavaPlugin", package: "swift-java"),
7979
]
8080
),
81+
82+
.testTarget(
83+
name: "JavaKitExampleTests",
84+
dependencies: [
85+
"JavaKitExample"
86+
],
87+
swiftSettings: [
88+
.swiftLanguageMode(.v5),
89+
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"])
90+
]
91+
),
8192
]
8293
)

Samples/JavaKitSampleApp/Sources/JavaKitExample/com/example/swift/ThreadSafeHelperClass.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,28 @@
2323
public class ThreadSafeHelperClass {
2424
public ThreadSafeHelperClass() { }
2525

26-
public Optional<String> text = Optional.of("");
26+
public Optional<String> text = Optional.of("cool string");
2727

2828
public final OptionalDouble val = OptionalDouble.of(2);
2929

3030
public String getValue(Optional<String> name) {
3131
return name.orElse("");
3232
}
3333

34+
35+
public String getOrElse(Optional<String> name) {
36+
return name.orElse("or else value");
37+
}
38+
39+
public Optional<String> getNil() {
40+
return Optional.empty();
41+
}
42+
43+
// @NonNull
44+
// public Optional<String> getNil() {
45+
// return Optional.empty();
46+
// }
47+
3448
public Optional<String> getText() {
3549
return text;
3650
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import JavaKitExample
16+
17+
import SwiftJava
18+
import JavaUtilFunction
19+
import Testing
20+
21+
@Suite
22+
struct ManglingTests {
23+
24+
@Test
25+
func methodMangling() throws {
26+
let jvm = try! JavaVirtualMachine.shared(
27+
classpath: [
28+
".build/plugins/outputs/javakitsampleapp/JavaKitExample/destination/JavaCompilerPlugin/Java"
29+
]
30+
)
31+
let env = try! jvm.environment()
32+
33+
let helper = ThreadSafeHelperClass(environment: env)
34+
35+
let text: JavaString? = helper.textOptional
36+
#expect(#"Optional("cool string")"# == String(describing: Optional("cool string")))
37+
#expect(#"Optional("cool string")"# == String(describing: text))
38+
39+
// let defaultValue: String? = helper.getOrElse(JavaOptional<JavaString>.empty())
40+
// #expect(#"Optional("or else value")"# == String(describing: defaultValue))
41+
42+
let noneValue: JavaOptional<JavaString> = helper.getNil()!
43+
#expect(noneValue.isPresent() == false)
44+
#expect("\(noneValue)" == "SwiftJava.JavaOptional<SwiftJava.JavaString>")
45+
46+
let textFunc: JavaString? = helper.getTextOptional()
47+
#expect(#"Optional("cool string")"# == String(describing: textFunc))
48+
49+
let doubleOpt: Double? = helper.valOptional
50+
#expect(#"Optional(2.0)"# == String(describing: doubleOpt))
51+
52+
let longOpt: Int64? = helper.fromOptional(21 as Int32?)
53+
#expect(#"Optional(21)"# == String(describing: longOpt))
54+
}
55+
56+
}

Samples/JavaKitSampleApp/ci-validate.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
set -e
44
set -x
55

6-
swift build
6+
swift build \
7+
--disable-experimental-prebuilts # FIXME: until prebuilt swift-syntax isn't broken on 6.2 anymore: https://github.com/swiftlang/swift-java/issues/418
8+
79
"$JAVA_HOME/bin/java" \
810
-cp .build/plugins/outputs/javakitsampleapp/JavaKitExample/destination/JavaCompilerPlugin/Java \
911
-Djava.library.path=.build/debug \

Sources/SwiftJava/AnyJavaObject.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,11 @@ public protocol AnyJavaObjectWithCustomClassLoader: AnyJavaObject {
5959
extension AnyJavaObject {
6060
/// Retrieve the underlying Java object.
6161
public var javaThis: jobject {
62-
javaHolder.object!
62+
javaHolder.object! // FIXME: this is a bad idea, can be null
63+
}
64+
65+
public var javaThisOptional: jobject? {
66+
javaHolder.object
6367
}
6468

6569
/// Retrieve the environment in which this Java object resides.

Sources/SwiftJava/JavaObject+Inheritance.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ extension AnyJavaObject {
2222
private func isInstanceOf<OtherClass: AnyJavaObject>(
2323
_ otherClass: OtherClass.Type
2424
) -> jclass? {
25-
try? otherClass.withJNIClass(in: javaEnvironment) { otherJavaClass in
26-
if javaEnvironment.interface.IsInstanceOf(
27-
javaEnvironment,
28-
javaThis,
29-
otherJavaClass
30-
) == 0 {
31-
return nil
32-
}
25+
guard let this: jobject = javaThisOptional else {
26+
return nil
27+
}
28+
29+
return try? otherClass.withJNIClass(in: javaEnvironment) { otherJavaClass in
30+
if javaEnvironment.interface.IsInstanceOf(javaEnvironment, this, otherJavaClass) == 0 {
31+
return nil
32+
}
3333

34-
return otherJavaClass
34+
return otherJavaClass
3535
}
3636
}
3737

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import CSwiftJavaJNI
16+
import JavaTypes
17+
18+
extension JavaString: CustomStringConvertible, CustomDebugStringConvertible {
19+
public var description: String {
20+
return toString()
21+
}
22+
public var debugDescription: String {
23+
return "\"" + toString() + "\""
24+
}
25+
}
26+
27+
extension Optional where Wrapped == JavaString {
28+
public var description: String {
29+
switch self {
30+
case .some(let value): "Optional(\(value.toString())"
31+
case .none: "nil"
32+
}
33+
}
34+
}

Sources/SwiftJava/Macros.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ public macro JavaStaticField(_ javaFieldName: String? = nil, isFinal: Bool = fal
124124
///
125125
/// corresponds to the Java constructor `HelloSwift(String name)`.
126126
@attached(body)
127-
public macro JavaMethod() = #externalMacro(module: "SwiftJavaMacros", type: "JavaMethodMacro")
127+
public macro JavaMethod(
128+
genericResult: String? = nil
129+
) = #externalMacro(module: "SwiftJavaMacros", type: "JavaMethodMacro")
128130

129131
/// Attached macro that turns a Swift method on JavaClass into one that wraps
130132
/// a Java static method on the underlying Java class object.

Sources/SwiftJava/Optional+JavaOptional.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,17 @@ public extension Optional where Wrapped == Int64 {
7979
}
8080
}
8181
}
82+
83+
extension JavaOptional {
84+
public func empty(environment: JNIEnvironment? = nil) -> JavaOptional<T>! {
85+
guard let env = try? environment ?? JavaVirtualMachine.shared().environment() else {
86+
return nil
87+
}
88+
89+
guard let opt = try? JavaClass<JavaOptional<T>>(environment: env).empty() else {
90+
return nil
91+
}
92+
93+
return opt.as(JavaOptional<T>.self)
94+
}
95+
}

Sources/SwiftJava/String+Extensions.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
import Foundation
16-
// import SwiftJavaToolLib
17-
// import SwiftJava
18-
// import JavaUtilJar
19-
// import SwiftJavaConfigurationShared
2016

2117
extension String {
2218
/// For a String that's of the form java.util.Vector, return the "Vector"

0 commit comments

Comments
 (0)