From b86f3936b0a9c64bec0fb0c15793dd9d93edd57b Mon Sep 17 00:00:00 2001 From: Amr Hesham Date: Sun, 19 Jul 2026 18:40:26 +0200 Subject: [PATCH] jextract: Move JNI pattern matching for Java Known interfaces --- ...ISwift2JavaGenerator+JavaTranslation.swift | 52 +++++--------- ...wift2JavaGenerator+NativeTranslation.swift | 70 ++++++------------- .../KnownFunctionalInterfaces.swift | 16 +++++ 3 files changed, 56 insertions(+), 82 deletions(-) diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift index 81db978da..4fa6a3a95 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift @@ -696,25 +696,6 @@ extension JNISwift2JavaGenerator { nativeFunctionSignature.result.outParameters.append(.init(name: "result_future", type: nativeFutureType)) } - func extractKnownJavaFunctionalInterfaceType( - swiftType: SwiftType, - functionType: SwiftFunctionType, - parameterName: String, - parameterAnnotations: [JavaAnnotation] - ) -> TranslatedParameter? { - if !functionType.isEscaping && functionType.parameters.isEmpty && functionType.resultType.isVoid { - return TranslatedParameter( - parameter: JavaParameter( - name: parameterName, - type: JavaType.javaLangRunnable, - annotations: parameterAnnotations, - ), - conversion: .placeholder, - ) - } - return nil - } - func translateFunctionParameter( swiftType: SwiftType, functionType: SwiftFunctionType, @@ -723,23 +704,24 @@ extension JNISwift2JavaGenerator { parentName: SwiftQualifiedTypeName, parameterAnnotations: [JavaAnnotation] ) -> TranslatedParameter { - extractKnownJavaFunctionalInterfaceType( - swiftType: swiftType, - functionType: functionType, - parameterName: parameterName, - parameterAnnotations: parameterAnnotations + let interfacejavaType = + if let known = KnownJavaFunctionalInterface.find(functionType) { + known.javaType + } else { + JavaType.class( + package: javaPackage, + name: String.javaQualifiedName(parentName.fullName, methodName, parameterName) + ) + } + + return TranslatedParameter( + parameter: JavaParameter( + name: parameterName, + type: interfacejavaType, + annotations: parameterAnnotations, + ), + conversion: .placeholder, ) - ?? TranslatedParameter( - parameter: JavaParameter( - name: parameterName, - type: .class( - package: javaPackage, - name: String.javaQualifiedName(parentName.fullName, methodName, parameterName) - ), - annotations: parameterAnnotations, - ), - conversion: .placeholder, - ) } func translateProtocolParameter( diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+NativeTranslation.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+NativeTranslation.swift index 8a54532c5..9fe9b6c13 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+NativeTranslation.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+NativeTranslation.swift @@ -362,31 +362,6 @@ extension JNISwift2JavaGenerator { ) } - func extractKnownJavaFunctionalInterfaceType( - functionType: SwiftFunctionType, - parameterName: String, - parameters: [JNISwift2JavaGenerator.NativeParameter], - result: JNISwift2JavaGenerator.NativeResult - ) -> NativeParameter? { - if !functionType.isEscaping && functionType.parameters.isEmpty && functionType.resultType.isVoid { - return NativeParameter( - parameters: [ - JavaParameter( - name: parameterName, - type: JavaType.javaLangRunnable - ) - ], - conversion: .closureLowering( - parameters: parameters, - result: result - ), - indirectConversion: nil, - conversionCheck: nil - ) - } - return nil - } - func translateFunctionParameter( swiftType: SwiftType, functionType: SwiftFunctionType, @@ -456,29 +431,30 @@ extension JNISwift2JavaGenerator { } let result = try translateClosureResult(functionType.resultType) - return extractKnownJavaFunctionalInterfaceType( - functionType: functionType, - parameterName: parameterName, - parameters: parameters, - result: result + let interfaceJavaType = + if let known = KnownJavaFunctionalInterface.find(functionType) { + known.javaType + } else { + JavaType.class( + package: javaPackage, + name: String.javaQualifiedName(parentName.fullName, methodName, parameterName) + ) + } + + return NativeParameter( + parameters: [ + JavaParameter( + name: parameterName, + type: interfaceJavaType + ) + ], + conversion: .closureLowering( + parameters: parameters, + result: result + ), + indirectConversion: nil, + conversionCheck: nil ) - ?? NativeParameter( - parameters: [ - JavaParameter( - name: parameterName, - type: .class( - package: javaPackage, - name: String.javaQualifiedName(parentName.fullName, methodName, parameterName) - ) - ) - ], - conversion: .closureLowering( - parameters: parameters, - result: result - ), - indirectConversion: nil, - conversionCheck: nil - ) } func translateProtocolParameter( diff --git a/Sources/JExtractSwiftLib/KnownFunctionalInterfaces.swift b/Sources/JExtractSwiftLib/KnownFunctionalInterfaces.swift index 7baa30645..ddafc8a4a 100644 --- a/Sources/JExtractSwiftLib/KnownFunctionalInterfaces.swift +++ b/Sources/JExtractSwiftLib/KnownFunctionalInterfaces.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +import SwiftExtract import SwiftJavaJNICore /// Describes a known functional interface such as `Runnable.run()` and similar. @@ -48,6 +49,21 @@ struct KnownJavaFunctionalInterface: Sendable { find(parameters: methodSignature.parameterTypes, result: methodSignature.resultType) } + static func find(_ functionType: SwiftFunctionType) -> KnownJavaFunctionalInterface? { + if functionType.isEscaping { + return nil + } + + let parameters = functionType.parameters + let result = functionType.resultType + return switch (parameters, result) { + case ([], _) where result.isVoid: + runnable + default: + nil + } + } + static func find(_ functionType: JNISwift2JavaGenerator.TranslatedFunctionType) -> KnownJavaFunctionalInterface? { if functionType.isEscaping { return nil