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

Kotlin/JS: init function not added to package (leading to Uncaught TypeError) #482

Closed
FSteitz opened this issue Jun 14, 2019 · 2 comments
Closed

Comments

@FSteitz
Copy link

FSteitz commented Jun 14, 2019

Describe the bug
I have a base module in a separate project that already compiles Kotlin code to JavaScript. Which includes serialization code.

Another module in another project imports the base module and extends classes of it (let's say it produces a file called app.js). The code compiles, but once I run the app, I get the error Uncaught TypeError: AbstractRESTResponse_init is not a function when a JSON response is deserialized.

Apparently, the generated deserialization code tries to import a generated _init function that is not public / does not exist in the package.

Parent class (in base module):

@Serializable
abstract class AbstractRESTResponse(
        open val status: String,
        open val errorNumber: String?,
        open val errorMessage: String?,
        open val warningList: Collection<RESTResponseMessage>,
        open val infoList: Collection<RESTResponseMessage>
)

Child class (in app module):

@Serializable
class AppResourceResponse(
        @Transient override val status: String = "",
        @Transient override val errorNumber: String? = null,
        @Transient override val errorMessage: String? = null,
        @Transient override val warningList: Collection<RESTResponseMessage> = listOf(),
        @Transient override val infoList: Collection<RESTResponseMessage> = listOf(),
        val content: String
) : AbstractRESTResponse(status, errorNumber, errorMessage, warningList, infoList)

Once the JSON representing AppResourceResponse is deserialized, I get the following error:

app.js: Uncaught (in promise) TypeError: AbstractRESTResponse_init is not a function
    at AppResourceResponse_init (app.js:1312)
    at AppResourceResponse$$serializer.deserialize_nts5qn$ (app.js:1293)
    at decodeSerializableValuePolymorphic (Polymorphic.kt:33)
    at StreamingJsonInput.decodeSerializableValue_w63s0f$ (StreamingJsonInput.kt:29)
    at decode_0 (Core.kt:79)

After further investigation, I found the following lines in the generated JavaScript code of the base module:

AbstractRESTResponse$$serializer.prototype.deserialize_nts5qn$ = function (decoder) {
    ...
    return AbstractRESTResponse_init(bitMask0, local0, local1, local2, local3, local4, null);
}

function AbstractRESTResponse_init(seen1, status, errorNumber, errorMessage, warningList, infoList, serializationConstructorMarker) {
    ...
}

But the function AbstractRESTResponse_init is never made public via the package. That's why the following code in app.js fails:

var AbstractRESTResponse_init = $module$basis_ui.de.basis.ui.rest.AbstractRESTResponse_init_a66qd8$;
// AbstractRESTResponse_init is undefined after this.

...
function AppResourceResponse_init(seen1, content, serializationConstructorMarker) {
    var $this = serializationConstructorMarker || Object.create(AppResourceResponse.prototype);
    $this = AbstractRESTResponse_init(seen1, $this); // TypeError: AbstractRESTResponse_init is not a function
    ...
  }

I could work around this issue by copying the base classes which are extended into the app's module. The copied classes can also reference classes of the base module. As long as these classes are not extended.

I even tried to work around this issue by declaring a secondary constructor myself. But the compiler plugin always produces an additional _init function that won't be exported.

To Reproduce
Create a separate module for a Kotlin-based JavaScript library that already compiles serializer code. Another module imports this library and extends base classes of it and also compiles serializer code. Compilation works, but running the code results in an error.

Expected behavior
No error. Possibly by adding the _init function to the package.

Environment

  • Kotlin version: 1.3.31
  • Library version: 0.11.0
  • Kotlin platforms: JS
  • Maven version: 3.3.9
@sandwwraith
Copy link
Member

This looks like a duplicate of #443

@FSteitz
Copy link
Author

FSteitz commented Aug 9, 2019

I confirm that this bug is a duplicate and was fixed when #443 was fixed. Therefore, I will close this issue.

@FSteitz FSteitz closed this as completed Aug 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants