Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Json.parse fails on JS for types defined in commonTest which extend from types defined in commonMain. #443

Closed
Whathecode opened this issue Apr 23, 2019 · 5 comments
Labels

Comments

@Whathecode
Copy link
Contributor

Whathecode commented Apr 23, 2019

I am trying to upgrade my multiplatform project from Kotlin 1.3.21 and serialization 0.10.0 to Kotlin 1.3.30 and serialization 0.11.0.

After doing so, all my JVM tests pass, but many of my JS tests fail. I get errors along the lines of:

TypeError: SomeBaseClass_init is not a function

I have managed to create a small repro:

class AbstractBaseTest
{
    @Test
    fun concreteClass_test()
    {
        val concrete = ConcreteClass()
        val serialized: String = Json.stringify( ConcreteClass.serializer(), concrete )
        val parsed: ConcreteClass = Json.parse( ConcreteClass.serializer(), serialized )
    }

    @Test
    fun stubConcreteClass_test()
    {
        val concrete = StubConcreteClass()
        val serialized: String = Json.stringify( StubConcreteClass.serializer(), concrete )
        val parsed: StubConcreteClass = Json.parse( StubConcreteClass.serializer(), serialized )
    }
}

concreteClass_test() passes, but stubConcreteClass_test() fails on Json.parse:

TypeError: AbstractBase_init is not a function

The difference is ConcreteClass is defined in commonMain, whereas StubConcreteClass is defined in commonTest. The classes are just empty dummy classes.

@Serializable
abstract class AbstractBase

@Serializable
class ConcreteClass : AbstractBase()

@Serializable
class StubConcreteClass : AbstractBase()

Potentially related/relevant, since this seems a dependency issue. I copy JS test dependencies in build.gradle as follows, and this worked for the old version of Kotlin/serialization:

// JS test configuration.
// This is adapted from kotlinx-io's build file; I do not fully understand this configuration:
// https://stackoverflow.com/a/55244288/590790
apply plugin: 'com.moowork.node'
task copyJsDependencies(type: Copy, dependsOn: compileTestKotlinJs) {
    from compileKotlinJs.destinationDir
    into "${buildDir}/node_modules"

    def configuration = configurations.jsTestRuntimeClasspath
    from(files {
        configuration.collect { File file ->
            file.name.endsWith(".jar")
                    ? zipTree(file.absolutePath).matching {
                include '*.js'
                include '*.js.map' }
                    : files()
        }
    }.builtBy(configuration))
}
node {
    version = '11.12.0'
    download = true
}
task installMocha(type: NpmTask) {
    args = ['install', 'mocha']
}
task runMocha(type: NodeTask, dependsOn: [installMocha, compileTestKotlinJs, copyJsDependencies]) {
    script = file('node_modules/mocha/bin/mocha')
    args = [compileTestKotlinJs.outputFile]
}
jsTest.dependsOn runMocha

Full code is available in the repro.

@Whathecode
Copy link
Contributor Author

Still happens in Kotlin 1.3.31 and serialization 0.11.0.

Whathecode added a commit to cph-cachet/carp.core-kotlin that referenced this issue May 20, 2019
JVM tests still pass, but JavaScript tests now fail. This seems to be a `kotlinx.serialization` bug: Kotlin/kotlinx.serialization#443
@Whathecode
Copy link
Contributor Author

Whathecode commented May 21, 2019

I've been looking a bit more into what fails exactly.

The JavaScript tests try to import name mangled _init functions from the dependent module.

var AbstractBase_init = $module$bleh.AbstractBase_init_a66qd8$;

Within the dependent module, however, the base class is packaged, but not the _init function.

package$bleh.AbstractBase = AbstractBase;
// The following is NOT defined!
package$bleh.AbstractBase_init = AbstractBase_init;

Furthermore, AbstractBase_init is not mangled in the module definition.

This seems like a compiler error? After modifying the generated JS files to export all _init definitions, and matching them up correctly where they deviate, all tests pass!

@Whathecode
Copy link
Contributor Author

Any plans on fixing this?

This is currently keeping me locked on Kotlin 1.3.21, which prevents me from upgrading to Gradle > 5.3 due to the following bug, further complicating the publication of my multiplatform library.

@sandwwraith
Copy link
Member

@Whathecode I've reproduced the issue and currently investigating it

@sandwwraith
Copy link
Member

@Whathecode Fix will be available in Kotlin 1.3.41

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants