Skip to content

Commit 310798b

Browse files
committed
introduce some initial docc files
1 parent 867128b commit 310798b

File tree

8 files changed

+842
-787
lines changed

8 files changed

+842
-787
lines changed

.spi.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
version: 1
2+
builder:
3+
configs:
4+
- documentation_targets: [
5+
SwiftJava,
6+
JavaKit,
7+
SwiftKitSwift,
8+
JExtractSwift
9+
]

Package.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ let package = Package(
155155
.package(url: "https://github.com/ordo-one/package-benchmark", .upToNextMajor(from: "1.4.0")),
156156
],
157157
targets: [
158+
// Main target which serves as landing page for documentation
159+
.target(
160+
name: "SwiftJava"
161+
),
162+
158163
.macro(
159164
name: "JavaKitMacros",
160165
dependencies: [
@@ -413,3 +418,12 @@ let package = Package(
413418
)
414419
]
415420
)
421+
422+
switch ProcessInfo.processInfo.environment["SWIFT_DOCC"] {
423+
case "true", "TRUE", "yes", "YES", "1":
424+
package.dependencies.append(
425+
.package(url: "https://github.com/swiftlang/swift-docc-plugin", "1.0.0"..<"1.4.0")
426+
)
427+
default:
428+
()
429+
}
Lines changed: 112 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,112 @@
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-
// This is a "plain Swift" file containing various types of declarations,
16-
// that is exported to Java by using the `jextract-swift` tool.
17-
//
18-
// No annotations are necessary on the Swift side to perform the export.
19-
20-
#if os(Linux)
21-
import Glibc
22-
#elseif os(Windows)
23-
import CRT
24-
#elseif canImport(Darwin)
25-
import Darwin.C
26-
#endif
27-
28-
public func helloWorld() {
29-
p("\(#function)")
30-
}
31-
32-
public func globalTakeInt(i: Int) {
33-
p("i:\(i)")
34-
}
35-
36-
public func globalTakeIntInt(i: Int, j: Int) {
37-
p("i:\(i), j:\(j)")
38-
}
39-
40-
public func globalCallMeRunnable(run: () -> ()) {
41-
run()
42-
}
43-
44-
public class MySwiftClass {
45-
46-
public var len: Int
47-
public var cap: Int
48-
49-
public init(len: Int, cap: Int) {
50-
self.len = len
51-
self.cap = cap
52-
53-
p("\(MySwiftClass.self).len = \(self.len)")
54-
p("\(MySwiftClass.self).cap = \(self.cap)")
55-
let addr = unsafeBitCast(self, to: UInt64.self)
56-
p("initializer done, self = 0x\(String(addr, radix: 16, uppercase: true))")
57-
}
58-
59-
deinit {
60-
let addr = unsafeBitCast(self, to: UInt64.self)
61-
p("Deinit, self = 0x\(String(addr, radix: 16, uppercase: true))")
62-
}
63-
64-
public var counter: Int32 = 0
65-
66-
public func voidMethod() {
67-
p("")
68-
}
69-
70-
public func takeIntMethod(i: Int) {
71-
p("i:\(i)")
72-
}
73-
74-
public func echoIntMethod(i: Int) -> Int {
75-
p("i:\(i)")
76-
return i
77-
}
78-
79-
public func makeIntMethod() -> Int {
80-
p("make int -> 12")
81-
return 12
82-
}
83-
84-
public func makeRandomIntMethod() -> Int {
85-
return Int.random(in: 1..<256)
86-
}
87-
}
88-
89-
@_silgen_name("swift_getTypeByMangledNameInEnvironment")
90-
public func _getTypeByMangledNameInEnvironment(
91-
_ name: UnsafePointer<UInt8>,
92-
_ nameLength: UInt,
93-
genericEnvironment: UnsafeRawPointer?,
94-
genericArguments: UnsafeRawPointer?)
95-
-> Any.Type?
96-
97-
98-
// ==== Internal helpers
99-
100-
private func p(_ msg: String, file: String = #fileID, line: UInt = #line, function: String = #function) {
101-
print("[swift][\(file):\(line)](\(function)) \(msg)")
102-
fflush(stdout)
103-
}
104-
105-
#if os(Linux)
106-
// FIXME: why do we need this workaround?
107-
@_silgen_name("_objc_autoreleaseReturnValue")
108-
public func _objc_autoreleaseReturnValue(a: Any) {}
109-
110-
@_silgen_name("objc_autoreleaseReturnValue")
111-
public func objc_autoreleaseReturnValue(a: Any) {}
112-
#endif
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+
//// This is a "plain Swift" file containing various types of declarations,
16+
//// that is exported to Java by using the `jextract-swift` tool.
17+
////
18+
//// No annotations are necessary on the Swift side to perform the export.
19+
//
20+
//#if os(Linux)
21+
//import Glibc
22+
//#elseif os(Windows)
23+
//import CRT
24+
//#elseif canImport(Darwin)
25+
//import Darwin.C
26+
//#endif
27+
//
28+
//public func helloWorld() {
29+
// p("\(#function)")
30+
//}
31+
//
32+
//public func globalTakeInt(i: Int) {
33+
// p("i:\(i)")
34+
//}
35+
//
36+
//public func globalTakeIntInt(i: Int, j: Int) {
37+
// p("i:\(i), j:\(j)")
38+
//}
39+
//
40+
//public func globalCallMeRunnable(run: () -> ()) {
41+
// run()
42+
//}
43+
//
44+
//public class MySwiftClass {
45+
//
46+
// public var len: Int
47+
// public var cap: Int
48+
//
49+
// public init(len: Int, cap: Int) {
50+
// self.len = len
51+
// self.cap = cap
52+
//
53+
// p("\(MySwiftClass.self).len = \(self.len)")
54+
// p("\(MySwiftClass.self).cap = \(self.cap)")
55+
// let addr = unsafeBitCast(self, to: UInt64.self)
56+
// p("initializer done, self = 0x\(String(addr, radix: 16, uppercase: true))")
57+
// }
58+
//
59+
// deinit {
60+
// let addr = unsafeBitCast(self, to: UInt64.self)
61+
// p("Deinit, self = 0x\(String(addr, radix: 16, uppercase: true))")
62+
// }
63+
//
64+
// public var counter: Int32 = 0
65+
//
66+
// public func voidMethod() {
67+
// p("")
68+
// }
69+
//
70+
// public func takeIntMethod(i: Int) {
71+
// p("i:\(i)")
72+
// }
73+
//
74+
// public func echoIntMethod(i: Int) -> Int {
75+
// p("i:\(i)")
76+
// return i
77+
// }
78+
//
79+
// public func makeIntMethod() -> Int {
80+
// p("make int -> 12")
81+
// return 12
82+
// }
83+
//
84+
// public func makeRandomIntMethod() -> Int {
85+
// return Int.random(in: 1..<256)
86+
// }
87+
//}
88+
//
89+
//@_silgen_name("swift_getTypeByMangledNameInEnvironment")
90+
//public func _getTypeByMangledNameInEnvironment(
91+
// _ name: UnsafePointer<UInt8>,
92+
// _ nameLength: UInt,
93+
// genericEnvironment: UnsafeRawPointer?,
94+
// genericArguments: UnsafeRawPointer?)
95+
// -> Any.Type?
96+
//
97+
//
98+
//// ==== Internal helpers
99+
//
100+
//private func p(_ msg: String, file: String = #fileID, line: UInt = #line, function: String = #function) {
101+
// print("[swift][\(file):\(line)](\(function)) \(msg)")
102+
// fflush(stdout)
103+
//}
104+
//
105+
//#if os(Linux)
106+
//// FIXME: why do we need this workaround?
107+
//@_silgen_name("_objc_autoreleaseReturnValue")
108+
//public func _objc_autoreleaseReturnValue(a: Any) {}
109+
//
110+
//@_silgen_name("objc_autoreleaseReturnValue")
111+
//public func objc_autoreleaseReturnValue(a: Any) {}
112+
//#endif
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# JExtractSwift
2+
3+
The `jextract` approach to Java interoperability is primarily aimed at Java consumers of Swift libraries,
4+
and currently makes use of the [JDK-23 Foreign Function and Memory APIs](https://docs.oracle.com/en/java/javase/23/core/foreign-function-and-memory-api.html).
5+
6+
- **No code changes** need to be made to Swift libraries that are to be exposed to Java using jextract-swift.
7+
- Swift sources are compiled to `.swiftinterface` files
8+
- These `.swiftinterface` files are imported by jextract-swift which generates `*.java` files
9+
- The generated Java files contain generated code for efficient native invocations.
10+
11+
You can then use Swift libraries in Java just by calling the apropriate methods and initializers.
12+
13+
## Getting Started
14+
15+
This repository also includes the `jextract-swift` tool which is similar to the JDK's [`jextract`](https://github.com/openjdk/jextract/).
16+
17+
This approach is using Java's most recent (stable in JDK22) Foreign function and Memory APIs, collectively known as "Project Panama". You can read more about it here: https://openjdk.org/projects/panama/ It promises much higher performance than traditional approaches using JNI, and is primarily aimed for calling native code from a Java application.
18+
19+
:warning: This feature requires JDK 22. The recommended way to install/manage JDKs is using [sdkman](https://sdkman.io):
20+
21+
```
22+
curl -s "https://get.sdkman.io" | bash
23+
sdk install java 22-open
24+
25+
export JAVA_HOME=$(sdk home java 22-open)
26+
```
27+
28+
`jextract-swift` can be pointed at `*.swiftinterface` files and will generate corresponding Java files that use the (new in Java 22) Foreign Function & Memory APIs to expose efficient ways to call "down" into Swift from Java.
29+
30+
## JExtract: Swift <-> Java Type mapping
31+
32+
### Closures and Callbacks
33+
34+
A Swift function may accept a closure which is used as a callback:
35+
36+
```swift
37+
func callMe(maybe: () -> ()) {}
38+
```
39+
40+
41+
42+
## `jextract-swift` importer behavior
43+
44+
Only `public` functions, properties and types are imported.
45+
46+
Global Swift functions become static functions on on a class with the same name as the Swift module in Java,
47+
48+
```swift
49+
// Swift (Sources/SomeModule/Example.swift)
50+
51+
public func globalFunction()
52+
```
53+
54+
becomes:
55+
56+
```java
57+
// Java (SomeModule.java)
58+
59+
public final class SomeModule ... {
60+
public static void globalFunction() { ... }
61+
}
62+
```

0 commit comments

Comments
 (0)