Skip to content

Commit 93568ca

Browse files
diederichktoso
authored andcommitted
fix init naming mismatch
Java's `init` methods are bridged as is and made swift compatible via the backticks. At runtime though, this is forgotten and the java methods are looked up _with_ the backticks. This approach of fixing adds a `@JavaMethod("init")` annotation, which fixes the issue. (Though I'm not sure if this shouldn't be fixed in the generated macro code. Open for suggestions!)
1 parent cfb4b7b commit 93568ca

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

Sources/SwiftJavaToolLib/JavaClassTranslator.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,11 @@ extension JavaClassTranslator {
698698
}
699699
// Do we need to record any generic information, in order to enable type-erasure for the upcalls?
700700
var parameters: [String] = []
701+
// If the method name is "init", we need to explicitly specify it in the annotation
702+
// because "init" is a Swift keyword and will be escaped in the function name via `init`
703+
if javaMethod.getName() == "init" {
704+
parameters.append("\"init\"")
705+
}
701706
if hasTypeEraseGenericResultType {
702707
parameters.append("typeErasedResult: \"\(resultType)\"")
703708
}

Tests/SwiftJavaToolLibTests/WrapJavaTests/BasicWrapJavaTests.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ final class BasicWrapJavaTests: XCTestCase {
9999
100100
class SuperClass {
101101
public static final long serialVersionUID = 1L;
102+
public void init() throws Exception {}
102103
}
103104
104105
class SubClass extends SuperClass {
@@ -128,4 +129,37 @@ final class BasicWrapJavaTests: XCTestCase {
128129
]
129130
)
130131
}
132+
133+
// Test that Java methods named "init" get @JavaMethod("init") annotation.
134+
// Since "init" is a Swift keyword and gets escaped with backticks in the function name,
135+
// we explicitly specify the Java method name in the annotation.
136+
// See KeyAgreement.init() methods as a real-world example.
137+
func test_wrapJava_initMethodAnnotation() async throws {
138+
let classpathURL = try await compileJava(
139+
"""
140+
package com.example;
141+
142+
class TestClass {
143+
public void init(String arg) throws Exception {}
144+
public void init() throws Exception {}
145+
}
146+
""")
147+
148+
try assertWrapJavaOutput(
149+
javaClassNames: [
150+
"com.example.TestClass"
151+
],
152+
classpath: [classpathURL],
153+
expectedChunks: [
154+
"""
155+
@JavaMethod("init")
156+
open func `init`(_ arg0: String) throws
157+
""",
158+
"""
159+
@JavaMethod("init")
160+
open func `init`() throws
161+
""",
162+
]
163+
)
164+
}
131165
}

0 commit comments

Comments
 (0)