Invalid JVM class generated from Swift with parameter name overloads

w/ silver 2181:

The source:
open class DataOrError: NSObject
{

    fileprivate(set) open var error: String?
    fileprivate(set) open var data: String?
    
    public init(data: String)
    {
        self.data = data
    }
    
    public init(error: String)
    {
        self.error = error
    }
    
    open class func data(_ data: String) -> DataOrError
    {
        return DataOrError(data: data)
    }
    
    open class func error(_ error: String) -> DataOrError
    {
        return DataOrError(error: error)
    }
}

i.e. w/ the init method overloaded by parameter name:

Generates JVM code with invalid duplicated constructors:
 $ javap portableinterop/DataOrError
  Compiled from "<snip>/PortableInterop/ModelExtensions/Forms/DataOrError.swift"
  public class portableinterop.DataOrError {
    public portableinterop.DataOrError(java.lang.String);
    public portableinterop.DataOrError(java.lang.String);
    public static portableinterop.DataOrError data(java.lang.String);
    public static portableinterop.DataOrError error(java.lang.String);
    public java.lang.String geterror();
    public void seterror(java.lang.String);
    public java.lang.String getdata();
    public void setdata(java.lang.String);

This class can’t be loaded by the JVM, and causes a crash in the Android Studio 3.0.1 dexer “D8” (reported and fixed for 3.1)

.2181 is pretty old. Does this repro with the latest 9.3 release (.2211) and/or the current v10 builds?

Yep, this is on 2211:

Example project: consoleapplication444.zip (186.5 KB)

Output from javap showing duplicated constructor:

$ javap -cp consoleapplication444.jar consoleapplication444.DataOrError
Compiled from "/Users/jon/Desktop/consoleapplication444/Program.swift"
class consoleapplication444.DataOrError {
  public consoleapplication444.DataOrError(java.lang.String);
  public consoleapplication444.DataOrError(java.lang.String);
  public static consoleapplication444.DataOrError data(java.lang.String);
  public static consoleapplication444.DataOrError error(java.lang.String);
  public java.lang.String geterror();
  public void seterror(java.lang.String);
  public java.lang.String getdata();
  public void setdata(java.lang.String);
}

I’m not sure what the best answer codegen wise is, though, given you can do the suffixing as per method overloads. It probably should error rather than emit bad class files though.

Thanx. I’ll have a look first thing in the am.

1 Like