Skip to content

Commit 92a51f5

Browse files
committed
Add Support for Threadsafe and NotThreadSafe annotations
1 parent a26cb1a commit 92a51f5

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

Sources/Java2SwiftLib/JavaClassTranslator.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ struct JavaClassTranslator {
5252
/// The Swift names of the interfaces that this class implements.
5353
let swiftInterfaces: [String]
5454

55+
/// The annotations of the Java class
56+
let annotations: [Annotation]
57+
5558
/// The (instance) fields of the Java class.
5659
var fields: [Field] = []
5760

@@ -164,6 +167,8 @@ struct JavaClassTranslator {
164167
}
165168
}
166169

170+
self.annotations = javaClass.getAnnotations().compactMap(\.self)
171+
167172
// Collect all of the class members that we will need to translate.
168173
// TODO: Switch over to "declared" versions of these whenever we don't need
169174
// to see inherited members.
@@ -274,6 +279,7 @@ extension JavaClassTranslator {
274279
if let nativeMethodsProtocol = renderNativeMethodsProtocol() {
275280
allDecls.append(nativeMethodsProtocol)
276281
}
282+
allDecls.append(contentsOf: renderAnnotationExtensions())
277283
return allDecls
278284
}
279285

@@ -483,6 +489,30 @@ extension JavaClassTranslator {
483489
return protocolDecl.formatted(using: translator.format).cast(DeclSyntax.self)
484490
}
485491

492+
func renderAnnotationExtensions() -> [DeclSyntax] {
493+
var extensions: [DeclSyntax] = []
494+
495+
for annotation in annotations {
496+
let annotationName = annotation.annotationType().getName().splitSwiftTypeName().name
497+
if annotationName == "ThreadSafe" || annotationName == "Immutable" { // If we are threadsafe, mark as unchecked Sendable
498+
extensions.append(
499+
"""
500+
extension \(raw: swiftTypeName): @unchecked Swift.Sendable { }
501+
"""
502+
)
503+
} else if annotationName == "NotThreadSafe" { // If we are _not_ threadsafe, mark sendable unavailable
504+
extensions.append(
505+
"""
506+
@available(unavailable, *)
507+
extension \(raw: swiftTypeName): Swift.Sendable { }
508+
"""
509+
)
510+
}
511+
}
512+
513+
return extensions
514+
}
515+
486516
/// Render the given Java constructor as a Swift initializer.
487517
package func renderConstructor(
488518
_ javaConstructor: Constructor<some AnyJavaObject>

Sources/JavaKitReflection/JavaClass+Reflection.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,7 @@ extension JavaClass {
4343

4444
@JavaMethod
4545
public func getGenericInterfaces() -> [Type?]
46+
47+
@JavaMethod
48+
public func getAnnotations() -> [Annotation?]
4649
}

0 commit comments

Comments
 (0)