Skip to content

Commit b14ad9b

Browse files
authored
jextract: add support for desugared optional on Android 23 (#498)
1 parent f241b47 commit b14ad9b

3 files changed

Lines changed: 63 additions & 2 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2025 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+
public enum AndroidSupport {
16+
/// Performs any known name conversions
17+
/// for types that are desugared on specific Android versions
18+
public static func androidDesugarClassNameConversion(
19+
for fullClassName: String
20+
) -> String {
21+
#if os(Android) && compiler(>=6.3)
22+
switch fullClassName {
23+
case "java.util.Optional":
24+
// On API 23, Optionals are desugared
25+
if #unavailable(Android 24) {
26+
return "j$.util.Optional"
27+
}
28+
29+
default:
30+
break
31+
}
32+
#endif
33+
return fullClassName
34+
}
35+
}

‎Sources/SwiftJavaMacros/JavaClassMacro.swift‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ extension JavaClassMacro: MemberMacro {
7979
}
8080

8181
var members: [DeclSyntax] = []
82-
82+
8383
// Determine the modifiers to use for the fullJavaClassName member.
8484
let fullJavaClassNameMemberModifiers: String
8585
switch (isSwiftClass, isJavaLangObject) {
@@ -94,7 +94,13 @@ extension JavaClassMacro: MemberMacro {
9494
let classNameAccessSpecifier = isSwiftClass ? "open" : "public"
9595
members.append("""
9696
/// The full Java class name for this Swift type.
97-
\(raw: classNameAccessSpecifier) \(raw: fullJavaClassNameMemberModifiers) var fullJavaClassName: String { \(literal: className) }
97+
\(raw: classNameAccessSpecifier) \(raw: fullJavaClassNameMemberModifiers) var fullJavaClassName: String {
98+
#if os(Android)
99+
AndroidSupport.androidDesugarClassNameConversion(for: "\(raw: className)")
100+
#else
101+
"\(raw: className)"
102+
#endif
103+
}
98104
"""
99105
)
100106

‎Tests/SwiftJavaMacrosTests/JavaClassMacroTests.swift‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ class JavaKitMacroTests: XCTestCase {
4343
4444
/// The full Java class name for this Swift type.
4545
open override class var fullJavaClassName: String {
46+
#if os(Android)
47+
AndroidSupport.androidDesugarClassNameConversion(for: "org.swift.example.HelloWorld")
48+
#else
4649
"org.swift.example.HelloWorld"
50+
#endif
4751
}
4852
4953
public required init(javaHolder: JavaObjectHolder) {
@@ -150,7 +154,11 @@ class JavaKitMacroTests: XCTestCase {
150154
151155
/// The full Java class name for this Swift type.
152156
public static var fullJavaClassName: String {
157+
#if os(Android)
158+
AndroidSupport.androidDesugarClassNameConversion(for: "org.swift.example.HelloWorld")
159+
#else
153160
"org.swift.example.HelloWorld"
161+
#endif
154162
}
155163
156164
public typealias JavaSuperclass = JavaObject
@@ -242,7 +250,11 @@ class JavaKitMacroTests: XCTestCase {
242250
243251
/// The full Java class name for this Swift type.
244252
open override class var fullJavaClassName: String {
253+
#if os(Android)
254+
AndroidSupport.androidDesugarClassNameConversion(for: "org.swift.example.HelloWorld")
255+
#else
245256
"org.swift.example.HelloWorld"
257+
#endif
246258
}
247259
248260
public required init(javaHolder: JavaObjectHolder) {
@@ -283,7 +295,11 @@ class JavaKitMacroTests: XCTestCase {
283295
284296
/// The full Java class name for this Swift type.
285297
open class var fullJavaClassName: String {
298+
#if os(Android)
299+
AndroidSupport.androidDesugarClassNameConversion(for: "java.lang.Object")
300+
#else
286301
"java.lang.Object"
302+
#endif
287303
}
288304
289305
public var javaHolder: JavaObjectHolder
@@ -319,7 +335,11 @@ class JavaKitMacroTests: XCTestCase {
319335
320336
/// The full Java class name for this Swift type.
321337
open override class var fullJavaClassName: String {
338+
#if os(Android)
339+
AndroidSupport.androidDesugarClassNameConversion(for: "java.lang.Optional")
340+
#else
322341
"java.lang.Optional"
342+
#endif
323343
}
324344
325345
public required init(javaHolder: JavaObjectHolder) {

0 commit comments

Comments
 (0)