Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public struct Box<Element>: Hashable {
public init(count: Int64) {
self.count = count
}

public static func describeElement() -> String {
String(describing: Element.self)
}
}

public struct Fish: Hashable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ void fishBoxHasExpectedMethods() throws Exception {
Method setCount = fishBoxClass.getMethod("setCount", long.class);
assertNotNull(setCount);

// Static method
Method describeElement = fishBoxClass.getMethod("describeElement");
assertNotNull(describeElement);
assertEquals(String.class, describeElement.getReturnType());

// Constrained extension method (only on FishBox, not on Box)
Method describeFish = fishBoxClass.getMethod("describeFish");
assertNotNull(describeFish);
Expand All @@ -56,4 +61,9 @@ void boxHasGenericTypeParameter() {
"Box should have one generic type parameter");
assertEquals("Element", Box.class.getTypeParameters()[0].getName());
}

@Test
void callFishBoxStaticMethod() {
assertEquals("Fish", FishBox.describeElement());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -349,11 +349,19 @@ extension JNISwift2JavaGenerator {
}

for method in decl.methods {
if isEffectivelyGeneric && method.isStatic {
self.logger.debug("Skipping static method '\(method.name)' on unspecialized generic type '\(decl.effectiveJavaName)'")
continue
}
printFunctionDowncallMethods(&printer, method)
printer.println()
}

for variable in decl.variables {
if isEffectivelyGeneric && variable.isStatic {
self.logger.debug("Skipping static property '\(variable.name)' on unspecialized generic type '\(decl.effectiveJavaName)'")
continue
}
printFunctionDowncallMethods(&printer, variable)
printer.println()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,21 +366,23 @@ extension JNISwift2JavaGenerator {
guard let selfParameter else {
return nil
}

let isGeneric = selfParameter.selfType.asNominalTypeDeclaration?.isGeneric == true
if isGeneric {
return try self.translateParameter(
swiftType: .metatype(selfParameter.selfType),
parameterName: "selfTypePointer",
methodName: methodName,
parentName: parentName,
genericParameters: genericParameters,
genericRequirements: genericRequirements,
parameterPosition: nil,
)
} else {
guard isGeneric else {
return nil
}

switch selfParameter {
case .instance:
return TranslatedParameter(
parameter: JavaParameter(name: "selfTypePointer", type: .long),
conversion: .typeMetadataAddress(.placeholder),
)
case .staticMethod, .initializer:
return TranslatedParameter(
parameter: JavaParameter(name: "selfTypePointer", type: .long),
conversion: .constant("$typeMetadataAddressDowncall()"),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Use $typeMetadataAddressDowncall() instead of this.$typeMetadataAddress() because static methods cannot use this.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, thx!

)
}
}

func translateParameter(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1039,12 +1039,10 @@ extension JNISwift2JavaGenerator {
printer.println()
printer.printBraceBlock("extension \(type.swiftNominal.qualifiedName): \(protocolName)") { printer in
for variable in type.variables {
if variable.isStatic { continue }
printFunctionDecl(&printer, decl: variable, skipMethodBody: false)
}

for method in type.methods {
if method.isStatic { continue }
printFunctionDecl(&printer, decl: method, skipMethodBody: false)
}
}
Expand Down
10 changes: 0 additions & 10 deletions Sources/JExtractSwiftLib/Swift2JavaVisitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,6 @@ final class Swift2JavaVisitor {
functionSignature: signature,
)

if typeContext?.swiftNominal.isGeneric == true && typeContext?.isSpecialization != true && imported.isStatic {
log.debug("Skip importing static function in generic type: '\(node.qualifiedNameForDebug)'")
return
}

log.debug("Record imported method \(node.qualifiedNameForDebug)")
if let typeContext {
typeContext.methods.append(imported)
Expand Down Expand Up @@ -451,11 +446,6 @@ final class Swift2JavaVisitor {
functionSignature: signature,
)

if typeContext?.swiftNominal.isGeneric == true && typeContext?.isSpecialization != true && imported.isStatic {
log.debug("Skip importing static accessor in generic type: '\(node.qualifiedNameForDebug)'")
return
}

log.debug(
"Record imported variable accessor \(kind == .getter || kind == .subscriptGetter ? "getter" : "setter"):\(node.qualifiedNameForDebug)"
)
Expand Down
33 changes: 33 additions & 0 deletions Tests/JExtractSwiftTests/JNI/JNIGenericTypeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,39 @@ struct JNIGenericTypeTests {
)
}

@Test
func generateOpenerForGenericStaticMethod() throws {
let input =
#"""
public struct Box<Element> {
public static func describeElement() -> String {
"\(Element.self)"
}
}
"""#

try assertOutput(
input: input,
.jni,
.swift,
detectChunkByInitialLines: 2,
expectedChunks: [
"""
protocol _SwiftModule_Box_opener {
static func _describeElement(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass) -> jstring?
}
""",
#"""
extension Box: _SwiftModule_Box_opener {
static func _describeElement(environment: UnsafeMutablePointer<JNIEnv?>!, thisClass: jclass) -> jstring? {
return Box<Element>.describeElement().getJNILocalRefValue(in: environment)
}
}
"""#,
]
)
}

@Test
func genericValueInEnumCase() throws {
let input =
Expand Down
19 changes: 17 additions & 2 deletions Tests/JExtractSwiftTests/SpecializationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ struct SpecializationTests {
public func count() -> Int {
return items.count
}

public static func elementDescription() -> String {
return "\(Element.self)"
}
}

public struct Fish {
Expand All @@ -226,10 +230,21 @@ struct SpecializationTests {
input: input,
.jni,
.java,
detectChunkByInitialLines: 1,
detectChunkByInitialLines: 2,
expectedChunks: [
"public final class FishBox implements JNISwiftInstance {",
"public long count()",
"""
public long count() {
return FishBox.$count(this.$memoryAddress(), this.$typeMetadataAddress());
}
private static native long $count(long selfPointer, long selfTypePointer);
""",
"""
public static java.lang.String elementDescription() {
return FishBox.$elementDescription($typeMetadataAddressDowncall());
}
private static native java.lang.String $elementDescription(long selfTypePointer);
""",
],
)
}
Expand Down
Loading