Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Sources/ExampleSwiftLibrary/MySwiftLibrary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import Glibc
import CRT
#elseif canImport(Darwin)
import Darwin.C
#elseif canImport(Android)
import Android
#endif

public func helloWorld() {
Expand Down
35 changes: 35 additions & 0 deletions Sources/SwiftJava/AndroidSupport.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2025 Apple Inc. and the Swift.org project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Swift.org project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

public enum AndroidSupport {
/// Performs any known name conversions
/// for types that are desugared on specific Android versions
public static func androidDesugarClassNameConversion(
for fullClassName: String
) -> String {
#if os(Android) && compiler(>=6.3)
switch fullClassName {
case "java.util.Optional":
// On API 23, Optionals are desugared
if #unavailable(Android 24) {
return "j$.util.Optional"
}

default:
break
}
#endif
return fullClassName
}
}
16 changes: 11 additions & 5 deletions Sources/SwiftJavaMacros/JavaClassMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ extension JavaClassMacro: MemberMacro {
let superclass = specifiedSuperclass ?? "JavaObject"

// Check that the class name is fully-qualified, as it should be.
let className = classNameSegment.content.text
if className.firstIndex(of: ".") == nil {
throw MacroErrors.classNameNotFullyQualified(className)
let specifiedClassName = classNameSegment.content.text
if specifiedClassName.firstIndex(of: ".") == nil {
throw MacroErrors.classNameNotFullyQualified(specifiedClassName)
}

var members: [DeclSyntax] = []

// Determine the modifiers to use for the fullJavaClassName member.
let fullJavaClassNameMemberModifiers: String
switch (isSwiftClass, isJavaLangObject) {
Expand All @@ -94,7 +94,13 @@ extension JavaClassMacro: MemberMacro {
let classNameAccessSpecifier = isSwiftClass ? "open" : "public"
members.append("""
/// The full Java class name for this Swift type.
\(raw: classNameAccessSpecifier) \(raw: fullJavaClassNameMemberModifiers) var fullJavaClassName: String { \(literal: className) }
\(raw: classNameAccessSpecifier) \(raw: fullJavaClassNameMemberModifiers) var fullJavaClassName: String {
#if os(Android)
AndroidSupport.androidDesugarClassNameConversion(for: "\(raw: specifiedClassName)")
#else
"\(raw: specifiedClassName)"
#endif
}
"""
)

Expand Down
Loading