Skip to content

Commit cd5789e

Browse files
committed
Prepare summer of code summary posts
1 parent 8ca4abf commit cd5789e

14 files changed

+428
-0
lines changed

_data/authors.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,3 +551,27 @@ mitchellallison:
551551
552552
github: mitchellallison
553553
about: "Mitchell Allison works on Distributed Systems in Swift at Apple."
554+
555+
mads:
556+
name: Mads Odgaard
557+
558+
github: https://github.com/madsodgaard
559+
about: Mads is a Google Summer of Code 2025 contributor, where he worked on bringing JNI support to the jextract tool which is part of the Swift Java interoperability project.
560+
561+
ahmedelrefaey:
562+
name: Ahmed Elrefaey
563+
email:
564+
github: https://github.com/a7medev
565+
about: Ahmed is a Google Summer of Code 2025 contributor, where he worked on improving the display of Swift documentation during code completion in SourceKit-LSP and VSCode.
566+
567+
tien:
568+
name: Kelvin Bui
569+
570+
github: https://github.com/tienquocbui
571+
about: Kelvin is a Google Summer of Code 2025 code contributor, where he worked on improving the console output for Swift Testing.
572+
573+
priyambada:
574+
name: Priyambada Roul
575+
576+
github: https://github.com/roulpriya
577+
about: Priyambada is a Google Summer of Code 2025 code contributor, where she worked on providing Swiftly support in VSCode.
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
---
2+
layout: new-layouts/post
3+
published: true
4+
date: 2024-02-NN 10:00:00
5+
title: 'Swift GSoC 2024 highlight: Swiftly (Swift installer) support in Visual Studio Code
6+
author: [ktoso, priyambada]
7+
category: "Community"
8+
---
9+
10+
Another year of successful Swift participation in [Google Summer of Code](https://summerofcode.withgoogle.com) 2025 came to an end recently, and this year we'd like to shine some light on the projects and work acomplished during the summer!
11+
12+
Summer of Code is an annual program, organized by Google, which provides hands-on experience for newcomers contributing
13+
to open source projects. Participants usually are students, but do not have to be.
14+
15+
In this series of four posts, we'll highlight each of the Summer of Code contributors and their projects.
16+
You can navigate between the posts using these convenient links:
17+
18+
- Bringing Swiftly support to VS Code (this post)
19+
- [JNI mode for swift-java’s source jextract tool](./2025-11-NN-swift-gsoc-2024-highlight-2-swift-java-jextract-jni-mode.md)
20+
- [Improve the display of documentation during code completion in SourceKit-LSP](./2025-11-NN-swift-gsoc-2024-highlight-3-vscode-swift-lsp-documentation.md)
21+
- [Improved Console Output for Swift Testing](./2025-11-NN-swift-gsoc-2024-highlight-4-swift-testing-output.md)
22+
23+
What follows, is a shortened writeup about their project and experience by the GSoC contributors.
24+
If you'd like to learn more, please check out the full version of their posts on the Swift forums (linked below)!
25+
26+
---
27+
28+
## Bringing Swiftly support to VS Code
29+
30+
Hi Swift community! 👋
31+
32+
I am Priyambada Roul. I'm incredibly excited to share what I've been working on over the past three months as part of Google Summer of Code 2025 with Swift.org, alongside my mentors, @cmcgee1024 @matthewbastien
33+
34+
My project focused on integrating **Swiftly** (Swift's toolchain manager) into the **VS Code Swift extension.**
35+
36+
## The Problem We Solved
37+
38+
We've made switching toolchains easier with Swiftly, allowing you to install and switch between Swift versions without leaving VS Code.
39+
40+
1. **Switch Swift versions** with a single click
41+
42+
2. **Install new toolchains** without leaving VS Code
43+
44+
3. **See real-time progress** during installations
45+
46+
4. **Automatically sync** with project-specific Swift versions
47+
48+
## What's New for Swift Developers
49+
50+
### Swiftly VS Code Integration
51+
52+
The VS Code extension now provides an entirely **seamless toolchain management experience**:
53+
54+
* We now support macOS too!
55+
56+
* See your current Swift version in the VS Code status bar.
57+
58+
* Click the version to switch between installed toolchains instantly.
59+
60+
* Install any Swift version directly from VS Code with real-time progress.
61+
62+
* Automatic detection of .swift-version files with prompts to switch
63+
64+
### Enhanced Swiftly CLI
65+
66+
* Swiftly now supports a machine-readable JSON output format.
67+
68+
* Swiftly now reports toolchain installation progress updates in **JSONL format**
69+
70+
* We have polished error reporting.
71+
72+
![](/assets/images/gsoc-25/swiftly-1.jpg)
73+
74+
![](/assets/images/gsoc-25/swiftly-2.jpg)
75+
76+
![](/assets/images/gsoc-25/swiftly-3.jpg)
77+
78+
### Things I learnt
79+
80+
* Making a VS Code extension. While I have experience with TypeScript from web development, the VS Code extension API and its development workflow are different from what I'm used to.
81+
82+
* I understood the structure and distribution of Swift toolchains, as well as how different versions can coexist on the same system using symlinks, environment variables, and PATH manipulation, across both macOS and Linux.
83+
84+
* The extension spawns Swiftly processes and reads their JSON output streams in real-time. This involved learning about IPC mechanisms, stdin/stdout buffering and process lifecycle management.
85+
86+
Want to see what we built? Check out the repositories:
87+
88+
* **VS Code Swift Extension**: [github.com/swiftlang/vscode-swift](https://github.com/swiftlang/vscode-swift)
89+
90+
* **Swiftly CLI**: [github.com/swiftlang/swiftly](https://github.com/swiftlang/swiftly)
91+
92+
I have linked all pull requests and technical details in my **[detailed project report](https://docs.google.com/document/d/1Mnb9ybmVkpL6pAgrpMbSg6EV3owA2rz_FgltvAXdnUE/edit?tab=t.0)**, which provides an in-depth look into the specific changes.
93+
94+
This GSoC experience has been transformative. I came in as someone intimidated by large codebases, and I'm leaving with the confidence to tackle complex, multi-tool integrations. I'm excited to continue contributing to Swift community!
95+
96+
Thank you.
97+
98+
---
99+
100+
If you'd like to learn more about this project, please [check out the full post on the Swift forums](https://forums.swift.org/t/gsoc-2025-bringing-swiftly-support-to-vs-code/81886)!
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
---
2+
layout: new-layouts/post
3+
published: true
4+
date: 2024-02-NN 10:00:00
5+
title: 'Swift GSoC 2024 highlight: JNI mode for SwiftJava interoperability jextract tool
6+
author: [ktoso, mads]
7+
category: "Community"
8+
---
9+
10+
Another year of successful Swift participation in [Google Summer of Code](https://summerofcode.withgoogle.com) 2025 came to an end recently, and this year we'd like to shine some light on the projects and work acomplished during the summer!
11+
12+
Summer of Code is an annual program, organized by Google, which provides hands-on experience for newcomers contributing
13+
to open source projects. Participants usually are students, but do not have to be.
14+
15+
In this series of four posts, we'll highlight each of the Summer of Code contributors and their projects.
16+
17+
- [Bringing Swiftly support to VS Code](./2025-11-NN-swift-gsoc-2024-highlight-1-vscode-swiftly.md)
18+
- JNI mode for swift-java’s source jextract tool (this post)
19+
- [Improve the display of documentation during code completion in SourceKit-LSP](./2025-11-NN-swift-gsoc-2024-highlight-3-vscode-swift-lsp-documentation.md)
20+
- [Improved Console Output for Swift Testing](./2025-11-NN-swift-gsoc-2024-highlight-4-swift-testing-output.md)
21+
22+
---
23+
24+
## JNI mode for SwiftJava interoperability jextract tool
25+
26+
My name is Mads and I am excited to share with you what I have been working on for Swift/Java interoperability over the summer with my mentor Konrad for Google Summer of Code 2025.
27+
28+
# Overview
29+
30+
The [swift-java](https://github.com/swiftlang/swift-java) interoperability library provides the `swift-java jextract` tool, which automatically generates Java sources that are used to call Swift code from Java. Previously, this tool only worked using the [Foreign Function and Memory API (FFM)](https://docs.oracle.com/en/java/javase/21/core/foreign-function-and-memory-api.html), which requires JDK 22+, making it unavailable on platforms such as Android. The goal of this project was to extend the jextract tool, such that it is able to generate Java sources using JNI instead of FFM and thereby allowing more platforms to utilize Swift/Java interoperability.
31+
32+
I am very glad to report that we have succeeded in that goal, supporting even more features than initially planned! Our initial goal was to achieve feature parity with the FFM mode, but the new JNI mode also supports additional Swift language features such as enums and protocols!
33+
34+
With the outcome of this project, you can now run the following command to automatically generate Java wrappers for your Swift library using JNI, therefore opening up the possibility of using it on platforms such as Android.
35+
36+
```bash
37+
swift-java jextract --swift-module MySwiftLibrary \
38+
--mode jni \
39+
--input-swift Sources/MySwiftLibrary \
40+
--output-java out/java \
41+
--output-swift out/swift
42+
```
43+
44+
# How does it work?
45+
46+
The FFM mode already had the logic needed to analyze `.swift` or `.swiftinterface` files to gather the needed types, functions, variables, etc. for extraction. A lot of this logic was tied into the FFM based extraction, and therefore the initial step was to separate the analysis phase and the code-generation phase. This was done by introducing a protocol `Swift2JavaGenerator`, which has two implementations: one for FFM and one for JNI. In the future you could add more, such as Kotlin.
47+
48+
Having separated these two phases, we could start working on generating code that uses JNI. Fortunately, the `swift-java` project has since the beginning included JNI support using the `JavaKit` library *(recently renamed to `SwiftJava`)*. This means that developers could write Swift code that uses JNI in a safe and ergonomic way. Instead of generating raw JNI code, the source-generated code depends on `SwiftJava` and uses the conversion functions such as `getJNIValue()`, `init(fromJNI:)` for basic primitive types such as `Int64`, `Bool` and `String`
49+
50+
Each Swift class/struct is extracted as a single Java `class`. Functions and variables are generated as Java methods, that internally calls down to a native method that is implemented in Swift using `@_cdecl`. Take a look at the following example:
51+
52+
```swift
53+
public class MySwiftClass {
54+
public let x: Int64
55+
public init(x: Int64) {
56+
self.x = x
57+
}
58+
59+
public func printMe() {
60+
print(“\(self.x)”);
61+
}
62+
}
63+
```
64+
It is roughly generated to the equivalent Java `class`:
65+
```java
66+
public final class MySwiftClass implements JNISwiftInstance {
67+
public static MySwiftClass init(long x, long y, SwiftArena swiftArena$) {
68+
return MySwiftClass.wrapMemoryAddressUnsafe(MySwiftClass.$init(x, y), swiftArena$);
69+
}
70+
71+
public long getX() {
72+
return MySwiftClass.$getX(this.$memoryAddress());
73+
}
74+
75+
public void printMe() {
76+
MySwiftClass.$printMe(this.$memoryAddress());
77+
}
78+
79+
private static native long $init(long x, long y);
80+
private static native long $getX(long self);
81+
private static native void $printMe(long self);
82+
}
83+
```
84+
We also generate additional Swift thunks that actually implement the `native` methods and call the underlying Swift methods.
85+
86+
> You might notice that we are calling functions such as \`$memoryAddress()\` and `wrapMemoryAddressUnsafe`(). And why are we passing down a `long` to the native functions? Basically, the JNI wrappers store the address of the corresponding Swift instance and use it to pass it back to Swift in the native calls, allowing Swift to reconstruct a pointer to the instance and calling the respective function such as `printMe()`.
87+
88+
You can learn more about how the memory allocation and management works [in the full version of this post of this post on the Swift forums](https://forums.swift.org/t/gsoc-2025-new-jni-mode-added-to-swift-java-jextract-tool/81858)!
89+
90+
91+
An interesting aspect of an interoperability library such as `swift-java` is the memory management between the two sides, in this case the JVM and Swift. The FFM mode uses the FFM APIs around `MemorySegment` to allocate and manage native memory. We are not so lucky in JNI. In older Java versions there are different ways of allocating memory, such as `Unsafe` or `ByteBuffer.allocateDirect()`. We could have decided to use these and allocate memory on the Java side, like FFM, but instead we decided to move the responsibility to Swift, which allocates the memory instead. This had some nice upsides, as we did not have to mess the the witness tables like FFM does.
92+
93+
> For more info on memory in FFM, I strongly recommend watching Konrad’s talk [try\! Swift Tokyo 2025 \- Foreign Function and Memory APIs and Swift/Java interoperability](https://www.youtube.com/watch?v=vgtzhTOhEbs)
94+
95+
The most obvious place we need to allocate memory is when we initialize a wrapped Swift `class`. Take a look at the following generated code for a Swift initializer:
96+
```java
97+
public static MySwiftClass init(SwiftArena swiftArena$) {
98+
return MySwiftClass.wrapMemoryAddressUnsafe(MySwiftClass.$init(), swiftArena$);
99+
}
100+
private static native long $init();
101+
```
102+
Here we see that we are calling a native method `$init` which returns a `long`. This value is a pointer to the Swift instance in the memory space of Swift. It is passed to `wrapMemoryAddressUnsafe`, which is basically just storing the pointer in a local field and registering the wrapper to the `SwiftArena`.
103+
104+
`SwiftArena` is a type that is used to ensure we eventually deallocate the memory when the Java wrapper is no longer needed. There exists two implements of this:
105+
106+
1. `SwiftArena.ofConfined()`: returns a confined arena which is used with *try-with-resource*, to deallocate all instances at the end of some scope.
107+
2. `SwiftArena.ofAuto()`: returns an arena that deallocates instances once the garbage-collector has decided to do so.
108+
109+
This concept also exists in the FFM mode, and I recommend watching Konrad’s talk to learn more about them\!
110+
> Along with the JNI mode we also added support for providing `--memory-management-mode allow-global-automatic` to the tool, to allow a global `ofAuto()` arena as a default parameter, removing the need for explicitly passing around \`SwiftArena\`s.
111+
112+
If we take a look at the native implementation of `$init` in Swift, we see how we allocate and initialize the memory:
113+
```swift
114+
@_cdecl("Java_com_example_swift_MySwiftClass__00024init__JJ")
115+
func Java_com_example_swift_MySwiftClass__00024init__JJ(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass, x: jlong, y: jlong) -> jlong {
116+
let result$ = UnsafeMutablePointer<MySwiftClass>.allocate(capacity: 1)
117+
result$.initialize(to: MySwiftClass.init(x: Int64(fromJNI: x, in: environment!), y: Int64(fromJNI: y, in: environment!)))
118+
let resultBits$ = Int64(Int(bitPattern: result$))
119+
return resultBits$.getJNIValue(in: environment!)
120+
}
121+
```
122+
We are basically allocating memory for a single instance of `MySwiftClass`, initializing it to a new instance and returning the memory address of the pointer. It is the same approach for `struct` as well\!
123+
124+
# My experience with GSoC
125+
126+
Google Summer of Code was an awesome experience for me\! I got to work with my favourite language on a library that is very relevant\! A **HUGE** thanks to my mentor @ktoso, who provided invaluable guidance, was always available for questions and allowed me to experiment and take ownership of the work\!
127+
128+
I would definitely recommend GSoC to anyone interested, it is a great way to engage with the open-source community, develop your skills and work with some talented people\! My number one advice would be to never be afraid of asking seemingly “stupid” questions, they might not be that stupid afterall.
129+
130+
---
131+
132+
If you'd like to learn more about this project, please [check out the full post on the Swift forums](https://forums.swift.org/t/gsoc-2025-new-jni-mode-added-to-swift-java-jextract-tool/81858) as it contains lots of more additional examples and in-depth discussion about memory management and trade-offs this project had to resolve!

0 commit comments

Comments
 (0)