[Parcelize] Add test for parcelize in multiplatform setting.
This tests that classes in common code can have code generated for them in android compilations.
This commit is contained in:
+4
@@ -8,6 +8,10 @@ fun o() = "O"
|
|||||||
|
|
||||||
// MODULE: common2
|
// MODULE: common2
|
||||||
// TARGET_PLATFORM: Common
|
// TARGET_PLATFORM: Common
|
||||||
|
// The test framework adds additional files to common modules with no dependencies.
|
||||||
|
// Those files should only be added once, so we exclude them from common2 and only include
|
||||||
|
// them in common1.
|
||||||
|
// NO_COMMON_FILES
|
||||||
// FILE: common2.kt
|
// FILE: common2.kt
|
||||||
|
|
||||||
fun k() = "K"
|
fun k() = "K"
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// LANGUAGE: +MultiPlatformProjects
|
// LANGUAGE: +MultiPlatformProjects
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
// WITH_COROUTINES
|
|
||||||
|
|
||||||
// MODULE: common
|
// MODULE: common
|
||||||
// FILE: common.kt
|
// FILE: common.kt
|
||||||
@@ -10,6 +9,7 @@ expect interface I {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MODULE: main()()(common)
|
// MODULE: main()()(common)
|
||||||
|
// WITH_COROUTINES
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
import kotlin.coroutines.*
|
import kotlin.coroutines.*
|
||||||
import helpers.*
|
import helpers.*
|
||||||
|
|||||||
+7
@@ -47,4 +47,11 @@ object WasmEnvironmentConfigurationDirectives : SimpleDirectivesContainer() {
|
|||||||
val CHECK_TYPESCRIPT_DECLARATIONS by directive(
|
val CHECK_TYPESCRIPT_DECLARATIONS by directive(
|
||||||
description = "Check typescript declarations generated by the compiler",
|
description = "Check typescript declarations generated by the compiler",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val NO_COMMON_FILES by directive(
|
||||||
|
"""
|
||||||
|
Don't added helper files to prevent linking issues.
|
||||||
|
""".trimIndent(),
|
||||||
|
applicability = DirectiveApplicability.Global,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-12
@@ -355,18 +355,13 @@ class ModuleStructureExtractorImpl(
|
|||||||
directives = moduleDirectives,
|
directives = moduleDirectives,
|
||||||
languageVersionSettings = currentModuleLanguageVersionSettingsBuilder.build()
|
languageVersionSettings = currentModuleLanguageVersionSettingsBuilder.build()
|
||||||
)
|
)
|
||||||
if (testModule.frontendKind != FrontendKinds.FIR ||
|
additionalSourceProviders.flatMapTo(filesOfCurrentModule) { additionalSourceProvider ->
|
||||||
!testModule.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) ||
|
additionalSourceProvider.produceAdditionalFiles(
|
||||||
modules.isEmpty()
|
globalDirectives ?: RegisteredDirectives.Empty,
|
||||||
) {
|
testModule
|
||||||
additionalSourceProviders.flatMapTo(filesOfCurrentModule) { additionalSourceProvider ->
|
).also { additionalFiles ->
|
||||||
additionalSourceProvider.produceAdditionalFiles(
|
require(additionalFiles.all { it.isAdditional }) {
|
||||||
globalDirectives ?: RegisteredDirectives.Empty,
|
"Files produced by ${additionalSourceProvider::class.qualifiedName} should have flag `isAdditional = true`"
|
||||||
testModule
|
|
||||||
).also { additionalFiles ->
|
|
||||||
require(additionalFiles.all { it.isAdditional }) {
|
|
||||||
"Files produced by ${additionalSourceProvider::class.qualifiedName} should have flag `isAdditional = true`"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.js.test
|
package org.jetbrains.kotlin.js.test
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.js.JavaScript
|
import org.jetbrains.kotlin.js.JavaScript
|
||||||
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
||||||
@@ -20,6 +21,11 @@ import java.io.FileFilter
|
|||||||
class JsAdditionalSourceProvider(testServices: TestServices) : AdditionalSourceProvider(testServices) {
|
class JsAdditionalSourceProvider(testServices: TestServices) : AdditionalSourceProvider(testServices) {
|
||||||
override fun produceAdditionalFiles(globalDirectives: RegisteredDirectives, module: TestModule): List<TestFile> {
|
override fun produceAdditionalFiles(globalDirectives: RegisteredDirectives, module: TestModule): List<TestFile> {
|
||||||
if (JsEnvironmentConfigurationDirectives.NO_COMMON_FILES in module.directives) return emptyList()
|
if (JsEnvironmentConfigurationDirectives.NO_COMMON_FILES in module.directives) return emptyList()
|
||||||
|
// For multiplatform projects, add the files only to common modules with no dependencies.
|
||||||
|
if (module.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) &&
|
||||||
|
module.allDependencies.isNotEmpty()) {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
return getAdditionalKotlinFiles(module.files.first().originalFile.parent).map { it.toTestFile() }
|
return getAdditionalKotlinFiles(module.files.first().originalFile.parent).map { it.toTestFile() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
// WITH_STDLIB
|
||||||
|
|
||||||
|
@file:JvmName("TestKt")
|
||||||
|
package test
|
||||||
|
|
||||||
|
import android.os.Parcelable
|
||||||
|
import kotlinx.parcelize.*
|
||||||
|
|
||||||
|
annotation class TriggerParcelize
|
||||||
|
|
||||||
|
@TriggerParcelize
|
||||||
|
data class User(val name: String) : Parcelable
|
||||||
|
|
||||||
|
fun box() = parcelTest { parcel ->
|
||||||
|
val user = User("John")
|
||||||
|
user.writeToParcel(parcel, 0)
|
||||||
|
|
||||||
|
val bytes = parcel.marshall()
|
||||||
|
parcel.unmarshall(bytes, 0, bytes.size)
|
||||||
|
parcel.setDataPosition(0)
|
||||||
|
|
||||||
|
val user2 = parcelableCreator<User>().createFromParcel(parcel)
|
||||||
|
assert(user == user2)
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
// !LANGUAGE: +MultiPlatformProjects
|
||||||
|
// WITH_STDLIB
|
||||||
|
|
||||||
|
// Metadata compilations do not see through the expect/actuals and therefore,
|
||||||
|
// there are parcelize errors in metadata compilations.
|
||||||
|
// IGNORE_FIR_DIAGNOSTICS_DIFF
|
||||||
|
|
||||||
|
// MODULE: m1-common
|
||||||
|
// FILE: common.kt
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
expect interface MyParcelable
|
||||||
|
|
||||||
|
annotation class TriggerParcelize
|
||||||
|
|
||||||
|
@TriggerParcelize
|
||||||
|
data class User(val name: String) : MyParcelable
|
||||||
|
|
||||||
|
// MODULE: m2-jvm()()(m1-common)
|
||||||
|
// FILE: android.kt
|
||||||
|
|
||||||
|
@file:JvmName("TestKt")
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlinx.parcelize.*
|
||||||
|
|
||||||
|
actual typealias MyParcelable = android.os.Parcelable
|
||||||
|
|
||||||
|
fun box() = parcelTest { parcel ->
|
||||||
|
val user = User("John")
|
||||||
|
user.writeToParcel(parcel, 0)
|
||||||
|
|
||||||
|
val bytes = parcel.marshall()
|
||||||
|
parcel.unmarshall(bytes, 0, bytes.size)
|
||||||
|
parcel.setDataPosition(0)
|
||||||
|
|
||||||
|
val user2 = parcelableCreator<User>().createFromParcel(parcel)
|
||||||
|
assert(user == user2)
|
||||||
|
}
|
||||||
+12
@@ -19,6 +19,12 @@ import java.util.regex.Pattern;
|
|||||||
@TestMetadata("plugins/parcelize/parcelize-compiler/testData/box")
|
@TestMetadata("plugins/parcelize/parcelize-compiler/testData/box")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
public class ParcelizeFirLightTreeBoxTestGenerated extends AbstractParcelizeFirLightTreeBoxTest {
|
public class ParcelizeFirLightTreeBoxTestGenerated extends AbstractParcelizeFirLightTreeBoxTest {
|
||||||
|
@Test
|
||||||
|
@TestMetadata("additionalAnnotationTrigger.kt")
|
||||||
|
public void testAdditionalAnnotationTrigger() {
|
||||||
|
runTest("plugins/parcelize/parcelize-compiler/testData/box/additionalAnnotationTrigger.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllFilesPresentInBox() {
|
public void testAllFilesPresentInBox() {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/parcelize/parcelize-compiler/testData/box"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/parcelize/parcelize-compiler/testData/box"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
@@ -324,6 +330,12 @@ public class ParcelizeFirLightTreeBoxTestGenerated extends AbstractParcelizeFirL
|
|||||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/maps.kt");
|
runTest("plugins/parcelize/parcelize-compiler/testData/box/maps.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("mppWithExpectParcelable.kt")
|
||||||
|
public void testMppWithExpectParcelable() {
|
||||||
|
runTest("plugins/parcelize/parcelize-compiler/testData/box/mppWithExpectParcelable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nestedArrays.kt")
|
@TestMetadata("nestedArrays.kt")
|
||||||
public void testNestedArrays() {
|
public void testNestedArrays() {
|
||||||
|
|||||||
+12
@@ -19,6 +19,12 @@ import java.util.regex.Pattern;
|
|||||||
@TestMetadata("plugins/parcelize/parcelize-compiler/testData/box")
|
@TestMetadata("plugins/parcelize/parcelize-compiler/testData/box")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
public class ParcelizeIrBoxTestGenerated extends AbstractParcelizeIrBoxTest {
|
public class ParcelizeIrBoxTestGenerated extends AbstractParcelizeIrBoxTest {
|
||||||
|
@Test
|
||||||
|
@TestMetadata("additionalAnnotationTrigger.kt")
|
||||||
|
public void testAdditionalAnnotationTrigger() {
|
||||||
|
runTest("plugins/parcelize/parcelize-compiler/testData/box/additionalAnnotationTrigger.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllFilesPresentInBox() {
|
public void testAllFilesPresentInBox() {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/parcelize/parcelize-compiler/testData/box"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/parcelize/parcelize-compiler/testData/box"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
@@ -324,6 +330,12 @@ public class ParcelizeIrBoxTestGenerated extends AbstractParcelizeIrBoxTest {
|
|||||||
runTest("plugins/parcelize/parcelize-compiler/testData/box/maps.kt");
|
runTest("plugins/parcelize/parcelize-compiler/testData/box/maps.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("mppWithExpectParcelable.kt")
|
||||||
|
public void testMppWithExpectParcelable() {
|
||||||
|
runTest("plugins/parcelize/parcelize-compiler/testData/box/mppWithExpectParcelable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("nestedArrays.kt")
|
@TestMetadata("nestedArrays.kt")
|
||||||
public void testNestedArrays() {
|
public void testNestedArrays() {
|
||||||
|
|||||||
+2
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
|
|||||||
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
|
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
|
||||||
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrJvmResultsConverter
|
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrJvmResultsConverter
|
||||||
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
|
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
|
||||||
|
import org.jetbrains.kotlin.test.frontend.fir.FirMetaInfoDiffSuppressor
|
||||||
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
|
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
|
||||||
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirDiagnosticsHandler
|
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirDiagnosticsHandler
|
||||||
import org.jetbrains.kotlin.test.model.*
|
import org.jetbrains.kotlin.test.model.*
|
||||||
@@ -122,6 +123,7 @@ abstract class AbstractParcelizeFirBoxTestBase(val parser: FirParser) : Abstract
|
|||||||
+ENABLE_PLUGIN_PHASES
|
+ENABLE_PLUGIN_PHASES
|
||||||
FirDiagnosticsDirectives.FIR_PARSER with parser
|
FirDiagnosticsDirectives.FIR_PARSER with parser
|
||||||
}
|
}
|
||||||
|
useAfterAnalysisCheckers(::FirMetaInfoDiffSuppressor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -42,13 +42,17 @@ class ParcelizeEnvironmentConfigurator(testServices: TestServices) : Environment
|
|||||||
kotlinxCollectionsImmutable
|
kotlinxCollectionsImmutable
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Hard coding a name of an additional annotation for parcelize. Test that use this, need to provide the
|
||||||
|
// additional annotations as part of the test sources.
|
||||||
|
configuration.put(ParcelizeConfigurationKeys.ADDITIONAL_ANNOTATION, listOf("test.TriggerParcelize"))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun CompilerPluginRegistrar.ExtensionStorage.registerCompilerExtensions(
|
override fun CompilerPluginRegistrar.ExtensionStorage.registerCompilerExtensions(
|
||||||
module: TestModule,
|
module: TestModule,
|
||||||
configuration: CompilerConfiguration
|
configuration: CompilerConfiguration
|
||||||
) {
|
) {
|
||||||
val additionalAnnotation = configuration.get(ParcelizeConfigurationKeys.ADDITIONAL_ANNOTATION)
|
val additionalAnnotation = configuration.get(ParcelizeConfigurationKeys.ADDITIONAL_ANNOTATION) ?: emptyList()
|
||||||
ParcelizeComponentRegistrar.registerParcelizeComponents(
|
ParcelizeComponentRegistrar.registerParcelizeComponents(
|
||||||
this,
|
this,
|
||||||
additionalAnnotation,
|
additionalAnnotation,
|
||||||
|
|||||||
+3
-1
@@ -17,6 +17,8 @@ class ParcelizeUtilSourcesProvider(testServices: TestServices, baseDir: String =
|
|||||||
|
|
||||||
@OptIn(ExperimentalStdlibApi::class)
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
override fun produceAdditionalFiles(globalDirectives: RegisteredDirectives, module: TestModule): List<TestFile> {
|
override fun produceAdditionalFiles(globalDirectives: RegisteredDirectives, module: TestModule): List<TestFile> {
|
||||||
return listOf(File(libraryPath).toTestFile())
|
// Only provide the additional files for a JVM only module. In multiplatform tests, this ensures that the
|
||||||
|
// additional files are only provided once and in the right module.
|
||||||
|
return if (module.targetPlatform.all { it.platformName == "JVM" }) listOf(File(libraryPath).toTestFile()) else listOf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.wasm.test
|
package org.jetbrains.kotlin.wasm.test
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
|
||||||
|
import org.jetbrains.kotlin.test.directives.WasmEnvironmentConfigurationDirectives
|
||||||
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
|
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
|
||||||
import org.jetbrains.kotlin.test.model.TestFile
|
import org.jetbrains.kotlin.test.model.TestFile
|
||||||
import org.jetbrains.kotlin.test.model.TestModule
|
import org.jetbrains.kotlin.test.model.TestModule
|
||||||
@@ -24,7 +26,12 @@ class WasmWasiBoxTestHelperSourceProvider(testServices: TestServices) : Addition
|
|||||||
|
|
||||||
class WasmAdditionalSourceProvider(testServices: TestServices) : AdditionalSourceProvider(testServices) {
|
class WasmAdditionalSourceProvider(testServices: TestServices) : AdditionalSourceProvider(testServices) {
|
||||||
override fun produceAdditionalFiles(globalDirectives: RegisteredDirectives, module: TestModule): List<TestFile> {
|
override fun produceAdditionalFiles(globalDirectives: RegisteredDirectives, module: TestModule): List<TestFile> {
|
||||||
if (JsEnvironmentConfigurationDirectives.NO_COMMON_FILES in module.directives) return emptyList()
|
if (WasmEnvironmentConfigurationDirectives.NO_COMMON_FILES in module.directives) return emptyList()
|
||||||
|
// For multiplatform projects, add the files only to common modules with no dependencies.
|
||||||
|
if (module.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) &&
|
||||||
|
module.allDependencies.isNotEmpty()) {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
return getAdditionalKotlinFiles(module.files.first().originalFile.parent).map { it.toTestFile() }
|
return getAdditionalKotlinFiles(module.files.first().originalFile.parent).map { it.toTestFile() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user