Repair bootstrapping for wasm-ir module by removing class referencing
from constructor of kotlinx.serialization ir generator. Such references may be null if plugin was applied to the module, but no runtime was provided in current compile configuration (see added test).
This commit is contained in:
+16
-3
@@ -34,8 +34,8 @@ class IrPreGenerator(
|
||||
val irClass: IrClass,
|
||||
compilerContext: SerializationPluginContext,
|
||||
) : BaseIrGenerator(irClass, compilerContext) {
|
||||
private val serialDescriptorSymbol = compilerContext.getClassFromRuntime(SerialEntityNames.SERIAL_DESCRIPTOR_CLASS)
|
||||
fun generate() {
|
||||
|
||||
private fun generate() {
|
||||
preGenerateWriteSelfMethodIfNeeded()
|
||||
preGenerateDeserializationConstructorIfNeeded()
|
||||
}
|
||||
@@ -75,6 +75,7 @@ class IrPreGenerator(
|
||||
SERIALIZATION_PLUGIN_ORIGIN
|
||||
)
|
||||
// descriptor
|
||||
val serialDescriptorSymbol = compilerContext.getClassFromRuntime(SerialEntityNames.SERIAL_DESCRIPTOR_CLASS)
|
||||
method.addValueParameter(
|
||||
Name.identifier("serialDesc"), serialDescriptorSymbol.defaultType,
|
||||
SERIALIZATION_PLUGIN_ORIGIN
|
||||
@@ -93,7 +94,9 @@ class IrPreGenerator(
|
||||
private fun preGenerateDeserializationConstructorIfNeeded() {
|
||||
if (!irClass.isInternalSerializable) return
|
||||
// do not add synthetic deserialization constructor if .deserialize method is customized
|
||||
if (irClass.hasCompanionObjectAsSerializer && irClass.companionObject()?.findPluginGeneratedMethod(SerialEntityNames.LOAD) == null) return
|
||||
if (irClass.hasCompanionObjectAsSerializer && irClass.companionObject()
|
||||
?.findPluginGeneratedMethod(SerialEntityNames.LOAD) == null
|
||||
) return
|
||||
if (irClass.isValue) return
|
||||
if (irClass.findSerializableSyntheticConstructor() != null) return
|
||||
val ctor = irClass.addConstructor {
|
||||
@@ -120,4 +123,14 @@ class IrPreGenerator(
|
||||
if (this.isPrimitiveType(false)) this
|
||||
else this.makeNullable()
|
||||
|
||||
companion object {
|
||||
fun generate(
|
||||
irClass: IrClass,
|
||||
compilerContext: SerializationPluginContext
|
||||
) {
|
||||
if (!irClass.isInternalSerializable) return
|
||||
IrPreGenerator(irClass, compilerContext).generate()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -109,7 +109,7 @@ private class SerializerClassPreLowering(
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
irClass.runPluginSafe {
|
||||
IrPreGenerator(irClass, context).generate()
|
||||
IrPreGenerator.generate(irClass, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlinx.serialization
|
||||
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.runners.codegen.AbstractIrBlackBoxCodegenTest
|
||||
|
||||
open class AbstractSerializationWithoutRuntimeIrBoxTest : AbstractIrBlackBoxCodegenTest() {
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
builder.configureForKotlinxSerialization(emptyList())
|
||||
}
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlinx.serialization;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TargetBackend;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("plugins/kotlin-serialization/kotlin-serialization-compiler/testData/boxWithoutRuntime")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class SerializationWithoutRuntimeIrBoxTestGenerated extends AbstractSerializationWithoutRuntimeIrBoxTest {
|
||||
@Test
|
||||
public void testAllFilesPresentInBoxWithoutRuntime() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/kotlin-serialization/kotlin-serialization-compiler/testData/boxWithoutRuntime"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("basic.kt")
|
||||
public void testBasic() throws Exception {
|
||||
runTest("plugins/kotlin-serialization/kotlin-serialization-compiler/testData/boxWithoutRuntime/basic.kt");
|
||||
}
|
||||
}
|
||||
+4
@@ -21,6 +21,10 @@ fun main(args: Array<String>) {
|
||||
model("boxIr")
|
||||
}
|
||||
|
||||
testClass<AbstractSerializationWithoutRuntimeIrBoxTest> {
|
||||
model("boxWithoutRuntime")
|
||||
}
|
||||
|
||||
testClass<AbstractSerializationFirMembersTest> {
|
||||
model("firMembers")
|
||||
}
|
||||
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
// WITH_STDLIB
|
||||
|
||||
/**
|
||||
* This test checks that in the case when serialization plugin is applied, but kotlinx-serialization-core runtime is not present in compile classpath,
|
||||
* compilation of regular Kotlin classes still finishes succesfully.
|
||||
*
|
||||
* Such requirement is needed for cases when plugin is applied to a Gradle module, but runtime dependency is provided only in certain configurations,
|
||||
* e.g. only in `testImplementation` configuration (see :wasm:wasm-ir module). In such setup, production sources have plugin applied, but no runtime in classpath.
|
||||
*/
|
||||
|
||||
data class X(val i: Int) {
|
||||
companion object {
|
||||
fun x(): X = X(42)
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val i = X.x().i
|
||||
return if (i == 42) "OK" else i.toString()
|
||||
}
|
||||
Reference in New Issue
Block a user