Skip to content

Commit ddef48a

Browse files
authored
Merge pull request #37 from DougGregor/javakit-static-methods
Introduce the @JavaStaticMethod and use it for calling static Java methods
2 parents 080c2ae + 2d89c14 commit ddef48a

File tree

13 files changed

+47
-22
lines changed

13 files changed

+47
-22
lines changed

Sources/Java2Swift/JavaTranslator.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,9 @@ extension JavaTranslator {
416416

417417
let throwsStr = javaMethod.throwsCheckedException ? "throws" : ""
418418

419+
let methodAttribute: AttributeSyntax = javaMethod.isStatic ? "@JavaStaticMethod" : "@JavaMethod";
419420
return """
420-
@JavaMethod
421+
\(methodAttribute)
421422
public func \(raw: javaMethod.getName())\(raw: genericParameterClause)(\(raw: parametersStr))\(raw: throwsStr)\(raw: resultTypeStr)\(raw: whereClause)
422423
"""
423424
}

Sources/JavaKit/JavaObject+MethodCalls.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,10 @@ extension AnyJavaObject {
301301
extension JavaClass {
302302
/// Call a Java static method with the given name and arguments, which must be
303303
/// of the correct type, that produces the given result type.
304-
public func dynamicJavaMethodCall<each Param: JavaValue, Result: JavaValue>(
304+
public func dynamicJavaStaticMethodCall<each Param: JavaValue, Result: JavaValue>(
305305
methodName: String,
306-
args: repeat each Param
306+
arguments: repeat each Param,
307+
resultType: Result.Type
307308
) throws -> Result {
308309
let thisClass = javaThis
309310
let environment = javaEnvironment
@@ -325,7 +326,7 @@ extension JavaClass {
325326

326327
// Retrieve the method that performs this call, then
327328
let jniMethod = Result.jniStaticMethodCall(in: environment)
328-
let jniArgs = getJValues(repeat each args, in: environment)
329+
let jniArgs = getJValues(repeat each arguments, in: environment)
329330
let jniResult = try environment.translatingJNIExceptions {
330331
jniMethod(environment, thisClass, methodID, jniArgs)
331332
}
@@ -335,9 +336,9 @@ extension JavaClass {
335336

336337
/// Call a Java static method with the given name and arguments, which must be
337338
/// of the correct type, that produces the given result type.
338-
public func dynamicJavaMethodCall<each Param: JavaValue>(
339+
public func dynamicJavaStaticMethodCall<each Param: JavaValue>(
339340
methodName: String,
340-
args: repeat each Param
341+
arguments: repeat each Param
341342
) throws {
342343
let thisClass = javaThis
343344
let environment = javaEnvironment
@@ -359,7 +360,7 @@ extension JavaClass {
359360

360361
// Retrieve the method that performs this call, then
361362
let jniMethod = environment.interface.CallStaticVoidMethodA
362-
let jniArgs = getJValues(repeat each args, in: environment)
363+
let jniArgs = getJValues(repeat each arguments, in: environment)
363364
try environment.translatingJNIExceptions {
364365
jniMethod!(environment, thisClass, methodID, jniArgs)
365366
}

Sources/JavaKit/Macros.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public macro JavaField(_ javaFieldName: String? = nil) = #externalMacro(module:
9595

9696
/// Attached macro that turns a Swift method into one that wraps a Java method on the underlying Java object.
9797
///
98-
/// The macro must be used within either a AnyJavaObject-conforming type or a specific JavaClass instance.
98+
/// The macro must be used in an AnyJavaObject-conforming type.
9999
///
100100
/// ```swift
101101
/// @JavaMethod
@@ -115,6 +115,18 @@ public macro JavaField(_ javaFieldName: String? = nil) = #externalMacro(module:
115115
@attached(body)
116116
public macro JavaMethod() = #externalMacro(module: "JavaKitMacros", type: "JavaMethodMacro")
117117

118+
/// Attached macro that turns a Swift method on JavaClass into one that wraps
119+
/// a Java static method on the underlying Java class object.
120+
///
121+
/// The macro must be used within a specific JavaClass instance.
122+
///
123+
/// ```swift
124+
/// @JavaMethod
125+
/// func sayHelloBack(_ i: Int32) -> Double
126+
/// ```
127+
@attached(body)
128+
public macro JavaStaticMethod() = #externalMacro(module: "JavaKitMacros", type: "JavaMethodMacro")
129+
118130
/// Macro that exposes the given Swift method as a native method in Java.
119131
///
120132
/// The macro must be used within a struct type marked with `@JavaClass`, and there

Sources/JavaKitMacros/JavaMethodMacro.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ extension JavaMethodMacro: BodyMacro {
3434
fatalError("not a function")
3535
}
3636

37+
let isStatic = node.attributeName.trimmedDescription == "JavaStaticMethod"
3738
let funcName = funcDecl.name.text
3839
let params = funcDecl.signature.parameterClause.parameters
3940
let resultType: String =
@@ -54,7 +55,7 @@ extension JavaMethodMacro: BodyMacro {
5455
? "try" : "try!"
5556

5657
return [
57-
"return \(raw: tryKeyword) dynamicJavaMethodCall(methodName: \(literal: funcName)\(raw: parametersAsArgs)\(raw: resultType))"
58+
"return \(raw: tryKeyword) dynamicJava\(raw: isStatic ? "Static" : "")MethodCall(methodName: \(literal: funcName)\(raw: parametersAsArgs)\(raw: resultType))"
5859
]
5960
}
6061

Sources/JavaKitNetwork/generated/URI.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,6 @@ public struct URI {
125125
public func wait() throws
126126
}
127127
extension JavaClass<URI> {
128-
@JavaMethod
128+
@JavaStaticMethod
129129
public func create(_ arg0: String) -> URI?
130130
}

Sources/JavaKitNetwork/generated/URLClassLoader.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ public struct URLClassLoader {
7474
public func wait() throws
7575
}
7676
extension JavaClass<URLClassLoader> {
77-
@JavaMethod
77+
@JavaStaticMethod
7878
public func newInstance(_ arg0: [URL?]) -> URLClassLoader?
7979

80-
@JavaMethod
80+
@JavaStaticMethod
8181
public func getSystemResource(_ arg0: String) -> URL?
8282

83-
@JavaMethod
83+
@JavaStaticMethod
8484
public func getSystemResources(_ arg0: String) throws -> Enumeration<URL>?
8585
}

Sources/JavaKitNetwork/generated/URLConnection.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ extension JavaClass<URLConnection> {
146146
@JavaMethod
147147
public func setDefaultAllowUserInteraction(_ arg0: Bool)
148148

149-
@JavaMethod
149+
@JavaStaticMethod
150150
public func getDefaultAllowUserInteraction() -> Bool
151151

152152
@JavaMethod

Sources/JavaKitReflection/generated/AccessibleObject.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,6 @@ public struct AccessibleObject {
6565
public func wait() throws
6666
}
6767
extension JavaClass<AccessibleObject> {
68-
@JavaMethod
68+
@JavaStaticMethod
6969
public func setAccessible(_ arg0: [AccessibleObject?], _ arg1: Bool)
7070
}

Sources/JavaKitReflection/generated/Constructor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,6 @@ public struct Constructor<T: AnyJavaObject> {
122122
public func wait() throws
123123
}
124124
extension JavaClass {
125-
@JavaMethod
125+
@JavaStaticMethod
126126
public func setAccessible<T: AnyJavaObject>(_ arg0: [AccessibleObject?], _ arg1: Bool) where ObjectType == Constructor<T>
127127
}

Sources/JavaKitReflection/generated/Executable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,6 @@ public struct Executable {
119119
public func wait() throws
120120
}
121121
extension JavaClass<Executable> {
122-
@JavaMethod
122+
@JavaStaticMethod
123123
public func setAccessible(_ arg0: [AccessibleObject?], _ arg1: Bool)
124124
}

Sources/JavaKitReflection/generated/Method.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,6 @@ public struct Method {
137137
public func wait() throws
138138
}
139139
extension JavaClass<Method> {
140-
@JavaMethod
140+
@JavaStaticMethod
141141
public func setAccessible(_ arg0: [AccessibleObject?], _ arg1: Bool)
142142
}

Sources/_Subprocess/Subprocess+IO.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,10 @@ extension Subprocess {
145145
case fileDescriptor(FileDescriptor?, Bool)
146146
}
147147

148-
let storage: Mutex<Storage>
148+
let storage: LockedState<Storage>
149149

150150
internal init(storage: Storage) {
151-
self.storage = .init(storage)
151+
self.storage = .init(initialState: storage)
152152
}
153153

154154
internal func getReadFileDescriptor() -> FileDescriptor? {
@@ -250,10 +250,10 @@ extension Subprocess {
250250
case collected(Int, FileDescriptor?, FileDescriptor?)
251251
}
252252

253-
private let storage: Mutex<Storage>
253+
private let storage: LockedState<Storage>
254254

255255
internal init(storage: Storage) {
256-
self.storage = .init(storage)
256+
self.storage = .init(initialState: storage)
257257
}
258258

259259
internal func getWriteFileDescriptor() -> FileDescriptor? {

Tests/JavaKitTests/BasicRuntimeTests.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,14 @@ struct BasicRuntimeTests {
6666
#expect(String(describing: error) == "no protocol: bad url")
6767
}
6868
}
69+
70+
@Test("Static methods")
71+
func staticMethods() {
72+
let urlConnectionClass = JavaClass<URLConnection>(
73+
javaThis: URLConnection.getJNIClass(in: jvm.environment)!,
74+
environment: jvm.environment
75+
)
76+
77+
#expect(urlConnectionClass.getDefaultAllowUserInteraction() == false)
78+
}
6979
}

0 commit comments

Comments
 (0)