Skip to content

## Fix Swift overloads producing uncompilable Java wrappers#544

Open
Clemo97 wants to merge 6 commits intoswiftlang:mainfrom
Clemo97:main
Open

## Fix Swift overloads producing uncompilable Java wrappers#544
Clemo97 wants to merge 6 commits intoswiftlang:mainfrom
Clemo97:main

Conversation

@Clemo97
Copy link

@Clemo97 Clemo97 commented Jan 29, 2026

Fixes #526

Problem

Swift allows method overloading using parameter labels (argument labels), where methods can have the same base name but different parameter labels:

public func takeValue(a: String) {}
public func takeValue(b: String) {}

In Swift, these are distinct methods because parameter labels are part of the function signature. However, when translated to Java, both were being generated with the same signature, causing compilation failures:

public void takeValue(String) //   Compilation error: duplicate method

Error:

error: method takeValue(String) is already defined in class OverloadSample

Solution

Modified the Java method name generation in FFMSwift2JavaGenerator+JavaTranslation.swift to append parameter labels as suffixes, creating unique method names that preserve Swift semantics while ensuring valid Java code.

Implementation:

  • Parameter labels are joined with underscores (e.g., _a, _b)
  • Applied consistently to all methods (functions, initializers)
  • Getters and setters are excluded to maintain property access patterns

Example transformation:

// Swift
public func takeValue(a: String) {}
public func takeValue(b: String) {}
// Generated Java (Before)
public void takeValue(String a) //   Duplicate!
public void takeValue(String b) //   Compilation error

// Generated Java (After)
public void takeValue_a(String a) //   Unique
public void takeValue_b(String b) //   Compiles successfully

Changes

  • Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift: Added logic to append parameter labels to method names for disambiguation
  • Samples/SwiftJavaExtractFFMSampleApp/src/main/java/com/example/swift/HelloJava2Swift.java: Updated sample code to use new method naming convention (e.g., globalTakeInt_i(), init_len_cap())
  • Samples/SwiftJavaExtractFFMSampleApp/Sources/MySwiftLibrary/OverloadSample.swift: Added test cases with overloaded methods.

@Clemo97 Clemo97 requested a review from ktoso as a code owner January 29, 2026 15:38
@ktoso
Copy link
Collaborator

ktoso commented Jan 29, 2026

Thanks for the request.what’s a reasonable direction however we should only be doing this if we detect a method has conflicts, otherwise it could be pretty annoying. Many members don’t have overloads and we can still call them with her normal names after all.

Copy link
Collaborator

@ktoso ktoso left a comment

Choose a reason for hiding this comment

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

Yeap still missing the required logic.

Copy link
Collaborator

@ktoso ktoso left a comment

Choose a reason for hiding this comment

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

marking as requesting changes

@Clemo97
Copy link
Author

Clemo97 commented Feb 3, 2026

Thanks for the request.what’s a reasonable direction however we should only be doing this if we detect a method has conflicts, otherwise it could be pretty annoying. Many members don’t have overloads and we can still call them with her normal names after all.

Yeah, my thought is to add a conflict detection logic one of the FFM directories that will collect all methods that will be generated from a class, compute each methods java signtature without suffixes then use that to detect duplicates from overloading and add parameter label suffixes to conflicting ones. @copilot

@ktoso
Copy link
Collaborator

ktoso commented Feb 3, 2026

I appreciate the will to help out but please don’t just at a coding assistant and expect it to figure out the implementation.

when you’re contributing you are ultimately responsible for the quality of the code. Feel free to use coding assistants but please verify and adjust their results such that they are passing our standards for quality and achieve the goals set out.

Back on the topic of implementation: yeah basically we’ll need such “conflicting names” mapping and then do another pass over them applying the renaming

@Clemo97
Copy link
Author

Clemo97 commented Feb 3, 2026

I appreciate the will to help out but please don’t just at a coding assistant and expect it to figure out the implementation.

when you’re contributing you are ultimately responsible for the quality of the code. Feel free to use coding assistants but please verify and adjust their results such that they are passing our standards for quality and achieve the goals set out.

Back on the topic of implementation: yeah basically we’ll need such “conflicting names” mapping and then do another pass over them applying the renaming

Thanks for the feedback.

@ktoso
Copy link
Collaborator

ktoso commented Feb 11, 2026

@Clemo97 are you working on this actively? I'm a bit confused with the periodic merges here but no action taken on the requested change?

MySwiftLibrary.globalReceiveOptional_o1_o2(OptionalLong.of(12), Optional.of(dat));
var dat = Data.init(bytes, bytes.byteSize(), arena);
MySwiftLibrary.globalReceiveSomeDataProtocol(dat);
MySwiftLibrary.globalReceiveOptional(OptionalLong.of(12), Optional.of(dat));
Copy link
Collaborator

Choose a reason for hiding this comment

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

cool, now we need actual tests for the conflicting behavior please :)

/// Detects method name conflicts within a nominal type and marks methods that need parameter label suffixes.
/// This implements a two-pass approach: first detect conflicts, then apply suffixes only where needed.
/// Only marks methods as conflicting if they would have identical Java signatures (same parameter types).
func detectMethodNameConflicts(for decl: ImportedNominalType) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this be "detectJavaMethodNameDupes"? And can it please return a value instead of mutating self directly?

// Only mark methods as conflicting if they share the same Java signature
for group in signatureGroups where group.count > 1 {
for method in group {
methodsNeedingSuffixes.insert(ObjectIdentifier(method))
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't love the ObjectIdentifier because it will be hard to debug and print those; can you please use some readable representation for the storage? Can be string names I guess

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe all this needs to become a class which is "DuplicateNames" and inside there do the storage, detection and everything -- that'll be much cleaner

struct JavaTranslation {
let config: Configuration
var knownTypes: SwiftKnownTypes
let shouldAppendParameterLabels: Bool
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need this explicitly or should we pass the DuplicateNames call then during translate(), that might be cleaner than adding bools

// Conflict detected: append parameter labels for disambiguation
suffix = decl.functionSignature.parameters
.map { "_" + ($0.argumentLabel ?? "_") }
.joined()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Make this into a private method makeMethodNameWithParamsSuffix()

Copy link
Collaborator

Choose a reason for hiding this comment

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

The whole "javaName = makeJavaMethodName(decl)" and put the logic there

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.

Swift overloads produce uncompilable wrappers

2 participants