skiptools / skip

Skip transpiler for creating SwiftUI apps for iOS and Android
https://skip.tools
GNU Lesser General Public License v3.0
1.43k stars 38 forks source link

Extensions on Array that are not referenced in the compile unit may fail to `import skip.lib.Array`, thus resulting in the wrong Array type being used #134

Open marcprux opened 3 months ago

marcprux commented 3 months ago

If you have a Swift file with just a single extension on Array (or Collection):

public extension Array {
    func jsonString() -> String? {
        guard let data = try? JSONSerialization.data(withJSONObject: self, options: .fragmentsAllowed) else {
            return nil
        }
        return String(data: data, encoding: .utf8) ?? nil
    }
}

The resulting Kotlin will not add the explicit import skip.lib.Array line, thus resulting in the extension being incorrectly added to the kotlin.Array, and thereby preventing the extension from being used in the correct way.

For example, the above code will result in the javap -c bytecode:

public static final <Element> java.lang.String jsonString(Element[]);

If the Array type is referenced anywhere in the file, then we will add the explicit import skip.lib.Array line to the transpiled Kotlin, thereby resulting in the expected compiled code:

public static final <Element> java.lang.String jsonString(skip.lib.Array<Element>);

The symptom will be that the extension will simply not be found in any code that references the extension. The workaround is to simply reference the Array type somewhere in the compile unit, which will trigger Skip to add the explicit skip.lib.Array import. E.g., this will be sufficient:

private func doSomething(array: Array<Int>) { }
marcprux commented 3 months ago

Test case FeatureSupportTests.testExtendArrayShouldImportArray()

aabewhite commented 2 months ago

This should now be fixed in skip 0.8.50. Use File->Packages->Update to Latest to get the latest transpiler with the fix

benford-servicem8 commented 1 month ago

Thanks Abe, confirmed working.

Cheers, Ben