Skip to content

jextract: keep Swift names that are Java keywords out of generated Java - #954

Open
piercifani wants to merge 1 commit into
swiftlang:mainfrom
piercifani:jextract-java-identifiers
Open

piercifani wants to merge 1 commit into
swiftlang:mainfrom
piercifani:jextract-java-identifiers

Conversation

@piercifani

Copy link
Copy Markdown

Problem

In JNI mode, Swift names that are Java keywords, or that Swift writes with backticks, reached the generated Java as they are:

public func automationTag(price: Int64, long: Bool) -> String
public func scale(double: Double, int: Int64, `default`: Bool) -> Double
public enum Pricing { case quote(slug: String, long: Int64) }
public struct Side { public static var `default`: Side }
public func wait()

That generated:

  • boolean long and long int as parameters;
  • record Quote(java.lang.String slug, long long);
  • get`default`();
  • a wait() that redeclares Object.wait().

None of it compiles with javac. The Swift thunks broke the same way for parameters named class or default.

JNIJavaKitTests even expected long int as a Java parameter.

Changes

  • Parameter names, closure parameter names and enum-case payload names get a _ suffix when they are a Java keyword or a reserved Swift keyword: long_, int_, default_. This applies in both the Java bindings and the Swift thunks; argument labels are unchanged, so the thunk still calls scale(double: …, int: …, default: …).
  • Getter and setter names drop a property's backticks: getDefault().
  • Methods that would redeclare a final java.lang.Object method (getClass, notify, notifyAll, wait) get a _ suffix, the same way Java-keyword method names already do. That includes the getter of a property named class.

FFM mode builds its parameter names separately and is unchanged here.

Testing

  • New JavaKeywordTests (4 tests): keyword parameter names in the Java bindings and the Swift thunks, enum-case payload names, a backticked property, and wait/notify/the class getter.
  • JNIJavaKitTests updated: long int_ instead of long int.
  • End to end, outside the repository: a package built with JExtractSwiftPlugin whose API uses all of these names. The generated Java compiles with javac and the generated Swift builds in Swift 6 mode. From Java, wait_(), notify_(1), getClass_() and getDefault() reach Swift through their renamed JNI symbols.
  • swift test passes.

🤖 Generated with Claude Code

Swift parameters may be named `long`, `int`, `double`, `default` or `class`,
and properties may be written with backticks, such as `` `default` ``. In JNI
mode those names reached the generated Java as they are: `boolean long`,
`record Quote(String slug, long long)` and `get`default`()` don't compile,
and the Swift thunks had the same problem with `class` and `default`.

- Parameter names, closure parameter names and enum case payload names get a
  `_` suffix when they are Java keywords or reserved Swift keywords, in both
  the Java bindings and the Swift thunks. Argument labels stay as they are.
- Getter and setter names drop a property's backticks: `getDefault()`.
- Method names that would redeclare a final method of `java.lang.Object`
  (`getClass`, `notify`, `notifyAll`, `wait`), including the getter of a
  property named `class`, get a `_` suffix, as Java keywords already did.

JNIJavaKitTests expected `long int` as a Java parameter, which doesn't
compile; it now expects `long int_`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant