Skip to content

jextract: Organize java known functional interfaces#844

Merged
ktoso merged 3 commits into
swiftlang:mainfrom
AmrDeveloper:jextract_java_known_fn_interface
Jul 15, 2026
Merged

jextract: Organize java known functional interfaces#844
ktoso merged 3 commits into
swiftlang:mainfrom
AmrDeveloper:jextract_java_known_fn_interface

Conversation

@AmrDeveloper

Copy link
Copy Markdown
Contributor

Organize the Java known functional interfaces information in one place

Issue #811

@@ -1691,7 +1691,7 @@ extension JNISwift2JavaGenerator {

let methodName =
if parameters.isEmpty && nativeResult.javaType.isVoid {

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.

I'd like this to be if let known = KnownJavaFunctionalInterface(method, nativeResult.javaType) { ... } else { "apply" } maybe, so centralize the matching the signatures to the types

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.

I updated it to depend on parameters and result types, not sure if there is a better syntax or a way to do this

@AmrDeveloper AmrDeveloper force-pushed the jextract_java_known_fn_interface branch from 47ef6ed to f2c1a81 Compare July 14, 2026 15:17
@ktoso

ktoso commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Digging through this a bit more, the shape we want is more like:


struct KnownJavaFunctionalInterface: Sendable {
  let javaType: JavaType
  let method: String
  let parameters: [JavaType]
  let result: JavaType

  static let runnable = KnownJavaFunctionalInterface(
    JavaType.javaLangRunnable,
    method: "run",
    parameters: [],
    result: .void
  )

because I want the type name, method name, and types all in one place, rather than spread out in the other funcs.

Hope you don't mind if I apply this small change and we merge this; looking forward to follow ups handling the other types!

@ktoso

ktoso commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

I also noticed the functional interface usage isn't really complete... We're still emitting the @FunctionalInterface public interface Function even though we don't use it anymore. we Should fix that as well.

@AmrDeveloper

Copy link
Copy Markdown
Contributor Author

Digging through this a bit more, the shape we want is more like:


struct KnownJavaFunctionalInterface: Sendable {
  let javaType: JavaType
  let method: String
  let parameters: [JavaType]
  let result: JavaType

  static let runnable = KnownJavaFunctionalInterface(
    JavaType.javaLangRunnable,
    method: "run",
    parameters: [],
    result: .void
  )

because I want the type name, method name, and types all in one place, rather than spread out in the other funcs.

Hope you don't mind if I apply this small change and we merge this; looking forward to follow ups handling the other types!

I don't mind, and I can do that too :D

@AmrDeveloper

Copy link
Copy Markdown
Contributor Author

I also noticed the functional interface usage isn't really complete... We're still emitting the @FunctionalInterface public interface Function even though we don't use it anymore. we Should fix that as well.

Yes, I mentioned that here

#820 (comment)

Will handle it in follow-up

@ktoso

ktoso commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Would you want to do the follow up please?

Inside

  /// Print FFM Java binding descriptors for the imported Swift API.
  package func printJavaBindingDescriptorClass(
    _ printer: inout JavaPrinter,
    _ decl: ExtractedFunc,
  ) {

before we do

printJavaBindingDescriptorClass(&printer, cFunc, symbolLookup: currentSymbolLookup) { printer in

we need to guard it like

if let known = KnownJavaFunctionalInterface.find(parameters: cParameterTypes, result: cResultType) {
  // skip, this is a known type/shape (e.g. Runnable),
  // so there's no need to emit an one-off functional interface for it.
  continue
}

Would you make a follow up PR with that please?

@ktoso

ktoso commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Thanks!

@AmrDeveloper

Copy link
Copy Markdown
Contributor Author

Would you want to do the follow up please?

Inside

  /// Print FFM Java binding descriptors for the imported Swift API.
  package func printJavaBindingDescriptorClass(
    _ printer: inout JavaPrinter,
    _ decl: ExtractedFunc,
  ) {

before we do

printJavaBindingDescriptorClass(&printer, cFunc, symbolLookup: currentSymbolLookup) { printer in

we need to guard it like

if let known = KnownJavaFunctionalInterface.find(parameters: cParameterTypes, result: cResultType) {
  // skip, this is a known type/shape (e.g. Runnable),
  // so there's no need to emit an one-off functional interface for it.
  continue
}

Would you make a follow up PR with that please?

Yes, I will. I just wanted to make them small incremental changes so we can easily review and merge them in short iterations, and I can get a review of the language features to use :D

Thanks

@ktoso ktoso merged commit c6fc1c5 into swiftlang:main Jul 15, 2026
42 checks passed
@AmrDeveloper AmrDeveloper deleted the jextract_java_known_fn_interface branch July 15, 2026 05:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants