From 93d569d090d6a6ad9ef5d8ebced5f4769c42ffa3 Mon Sep 17 00:00:00 2001 From: "Yaroslav.Chernyshev" Date: Fri, 29 Oct 2021 12:33:49 +0300 Subject: [PATCH] [CHERRY PICKED FROM IJ] Fix KotlinFacetSettings serialization issues for compiler arguments GitOrigin-RevId: 29d3bab972fc797fab7244c16df21763055db0c4 Original commit: https://github.com/JetBrains/intellij-community/commit/4e9f0bfaef343536930276ba27f582a95613d121 --- .../CompilerArgumentsContentProspector.kt | 6 +- .../arguments/CompilerArgumentsSerializer.kt | 3 +- .../CompilerArgumentsContentProspectorTest.kt | 63 ++++++++++++------- .../CompilerArgumentsSerializationTest.kt | 24 ++++++- 4 files changed, 66 insertions(+), 30 deletions(-) diff --git a/jps/jps-common/src/org/jetbrains/kotlin/arguments/CompilerArgumentsContentProspector.kt b/jps/jps-common/src/org/jetbrains/kotlin/arguments/CompilerArgumentsContentProspector.kt index ab25c7ec55e..4d497f20551 100644 --- a/jps/jps-common/src/org/jetbrains/kotlin/arguments/CompilerArgumentsContentProspector.kt +++ b/jps/jps-common/src/org/jetbrains/kotlin/arguments/CompilerArgumentsContentProspector.kt @@ -24,10 +24,10 @@ object CompilerArgumentsContentProspector { mutableMapOf() private fun getCompilerArguments(kClass: KClass) = argumentPropertiesCache.getOrPut(kClass) { - kClass.memberProperties.filter { prop -> prop.annotations.singleOrNull { it is Argument } != null } + kClass.memberProperties.filter { prop -> prop.annotations.any { it is Argument } } } - private inline fun List>.filterByReturnType(predicate: (KType?) -> Boolean) = + private inline fun List>.filterByReturnType(predicate: (KType?) -> Boolean) = filter { predicate(it.returnType) }.mapNotNull { it.safeAs>() } fun getFlagCompilerArgumentProperties(kClass: KClass): List> = @@ -37,7 +37,7 @@ object CompilerArgumentsContentProspector { stringArgumentPropertiesCache.getOrPut(kClass) { getCompilerArguments(kClass).filterByReturnType { it?.classifier == String::class } } fun getArrayCompilerArgumentProperties(kClass: KClass): List?>> = - arrayArgumentPropertiesCache.getOrPut(kClass) { getCompilerArguments(kClass).filterByReturnType { it?.classifier?.javaClass?.isArray == true } } + arrayArgumentPropertiesCache.getOrPut(kClass) { getCompilerArguments(kClass).filterByReturnType { (it?.classifier as? KClass<*>)?.java?.isArray == true } } val freeArgsProperty: KProperty1> get() = CommonToolArguments::freeArgs diff --git a/jps/jps-common/src/org/jetbrains/kotlin/arguments/CompilerArgumentsSerializer.kt b/jps/jps-common/src/org/jetbrains/kotlin/arguments/CompilerArgumentsSerializer.kt index 9f0b8fbd2c7..7d8d73cc8d0 100644 --- a/jps/jps-common/src/org/jetbrains/kotlin/arguments/CompilerArgumentsSerializer.kt +++ b/jps/jps-common/src/org/jetbrains/kotlin/arguments/CompilerArgumentsSerializer.kt @@ -41,8 +41,7 @@ class CompilerArgumentsSerializerV5(override val argume ?.takeIf { it.get(arguments)?.contentEquals(it.get(newInstance)) != true } ?.get(arguments) ?.let { prop.name to it } - }.filterNot { it.second.isEmpty() } - .toMap() + }.toMap() saveArrayArguments(this, arrayArgumentsByName) val freeArgs = CompilerArgumentsContentProspector.freeArgsProperty.get(arguments) saveElementsList(this, FREE_ARGS_ROOT_ELEMENTS_NAME, FREE_ARGS_ELEMENT_NAME, freeArgs) diff --git a/jps/jps-common/test/CompilerArgumentsContentProspectorTest.kt b/jps/jps-common/test/CompilerArgumentsContentProspectorTest.kt index 4e51dbbaeff..29283937dd8 100644 --- a/jps/jps-common/test/CompilerArgumentsContentProspectorTest.kt +++ b/jps/jps-common/test/CompilerArgumentsContentProspectorTest.kt @@ -3,6 +3,8 @@ package org.jetbrains.kotlin.arguments import org.jetbrains.kotlin.cli.common.arguments.* import org.junit.Test +import org.junit.Assert.* +import kotlin.reflect.KProperty class CompilerArgumentsContentProspectorTest { @@ -13,9 +15,9 @@ class CompilerArgumentsContentProspectorTest { val stringProperties = CompilerArgumentsContentProspector.getStringCompilerArgumentProperties(K2JVMCompilerArguments::class) val arrayProperties = CompilerArgumentsContentProspector.getArrayCompilerArgumentProperties(K2JVMCompilerArguments::class) - assertContentEquals(flagProperties, k2JVMCompilerArgumentsFlagProperties) { sortedBy { it.name } } - assertContentEquals(stringProperties, k2JVMCompilerArgumentsStringProperties) { sortedBy { it.name } } - assertContentEquals(arrayProperties, k2JVMCompilerArgumentsArrayArgumentProperties) { sortedBy { it.name } } + assertContentEquals(flagProperties, k2JVMCompilerArgumentsFlagProperties) + assertContentEquals(stringProperties, k2JVMCompilerArgumentsStringProperties) + assertContentEquals(arrayProperties, k2JVMCompilerArgumentsArrayArgumentProperties) } @Test @@ -24,9 +26,9 @@ class CompilerArgumentsContentProspectorTest { val stringProperties = CompilerArgumentsContentProspector.getStringCompilerArgumentProperties(K2MetadataCompilerArguments::class) val arrayProperties = CompilerArgumentsContentProspector.getArrayCompilerArgumentProperties(K2MetadataCompilerArguments::class) - assertContentEquals(flagProperties, k2MetadataCompilerArgumentsFlagProperties) { sortedBy { it.name } } - assertContentEquals(stringProperties, k2MetadataCompilerArgumentsStringProperties) { sortedBy { it.name } } - assertContentEquals(arrayProperties, k2MetadataCompilerArgumentsArrayProperties) { sortedBy { it.name } } + assertContentEquals(flagProperties, k2MetadataCompilerArgumentsFlagProperties) + assertContentEquals(stringProperties, k2MetadataCompilerArgumentsStringProperties) + assertContentEquals(arrayProperties, k2MetadataCompilerArgumentsArrayProperties) } @Test @@ -35,9 +37,9 @@ class CompilerArgumentsContentProspectorTest { val stringProperties = CompilerArgumentsContentProspector.getStringCompilerArgumentProperties(K2JSCompilerArguments::class) val arrayProperties = CompilerArgumentsContentProspector.getArrayCompilerArgumentProperties(K2JSCompilerArguments::class) - assertContentEquals(flagProperties, k2JSCompilerArgumentsFlagProperties) { sortedBy { it.name } } - assertContentEquals(stringProperties, k2JSCompilerArgumentsStringProperties) { sortedBy { it.name } } - assert(arrayProperties.isEmpty()) { "Expected empty arrayProperties, but actual ${arrayProperties.joinToString { it.name }}" } + assertContentEquals(flagProperties, k2JSCompilerArgumentsFlagProperties) + assertContentEquals(stringProperties, k2JSCompilerArgumentsStringProperties) + assertContentEquals(arrayProperties, k2JSCompilerArgumentsArrayProperties) } @Test @@ -46,9 +48,9 @@ class CompilerArgumentsContentProspectorTest { val stringProperties = CompilerArgumentsContentProspector.getStringCompilerArgumentProperties(K2JSDceArguments::class) val arrayProperties = CompilerArgumentsContentProspector.getArrayCompilerArgumentProperties(K2JSDceArguments::class) - assertContentEquals(flagProperties, k2JSDceCompilerArgumentsFlagProperties) { sortedBy { it.name } } - assertContentEquals(stringProperties, k2JSDceCompilerArgumentsStringProperties) { sortedBy { it.name } } - assertContentEquals(arrayProperties, k2JSDceCompilerArgumentsArrayProperties) { sortedBy { it.name } } + assertContentEquals(flagProperties, k2JSDceCompilerArgumentsFlagProperties) + assertContentEquals(stringProperties, k2JSDceCompilerArgumentsStringProperties) + assertContentEquals(arrayProperties, k2JSDceCompilerArgumentsArrayProperties) } companion object { @@ -69,7 +71,6 @@ class CompilerArgumentsContentProspectorTest { CommonCompilerArguments::noInline, CommonCompilerArguments::skipMetadataVersionCheck, CommonCompilerArguments::skipPrereleaseCheck, - CommonCompilerArguments::allowKotlinPackage, CommonCompilerArguments::reportOutputFiles, CommonCompilerArguments::multiPlatform, CommonCompilerArguments::noCheckActual, @@ -91,19 +92,24 @@ class CompilerArgumentsContentProspectorTest { CommonCompilerArguments::disableUltraLightClasses, CommonCompilerArguments::useMixedNamedArguments, CommonCompilerArguments::expectActualLinker, + CommonCompilerArguments::extendedCompilerChecks, CommonCompilerArguments::disableDefaultScriptingPlugin, - CommonCompilerArguments::inferenceCompatibility + CommonCompilerArguments::inferenceCompatibility, + CommonCompilerArguments::suppressVersionWarnings ) private val commonCompilerArgumentsStringProperties = listOf( + CommonCompilerArguments::languageVersion, + CommonCompilerArguments::apiVersion, CommonCompilerArguments::intellijPluginRoot, CommonCompilerArguments::dumpPerf, CommonCompilerArguments::metadataVersion, CommonCompilerArguments::dumpDirectory, CommonCompilerArguments::dumpOnlyFqName, - CommonCompilerArguments::explicitApi + CommonCompilerArguments::explicitApi, + CommonCompilerArguments::kotlinHome ) - private val commonCompilerArgumentsArrayArgumentProperties = listOf( + private val commonCompilerArgumentsArrayProperties = listOf( CommonCompilerArguments::pluginOptions, CommonCompilerArguments::pluginClasspaths, CommonCompilerArguments::experimental, @@ -147,6 +153,8 @@ class CompilerArgumentsContentProspectorTest { K2JVMCompilerArguments::noExceptionOnExplicitEqualsForBoxedNull, K2JVMCompilerArguments::disableStandardScript, K2JVMCompilerArguments::strictMetadataVersionSemantics, + K2JVMCompilerArguments::suppressDeprecatedJvmTargetWarning, + K2JVMCompilerArguments::typeEnhancementImprovementsInStrictMode, K2JVMCompilerArguments::sanitizeParentheses, K2JVMCompilerArguments::allowNoSourceFiles, K2JVMCompilerArguments::emitJvmTypeAnnotations, @@ -180,10 +188,12 @@ class CompilerArgumentsContentProspectorTest { K2JVMCompilerArguments::stringConcat, K2JVMCompilerArguments::klibLibraries, K2JVMCompilerArguments::profileCompilerCommand, - K2JVMCompilerArguments::repeatCompileModules + K2JVMCompilerArguments::repeatCompileModules, + K2JVMCompilerArguments::lambdas, + K2JVMCompilerArguments::samConversions ) - private val k2JVMCompilerArgumentsArrayArgumentProperties = commonCompilerArgumentsArrayArgumentProperties + listOf( + private val k2JVMCompilerArgumentsArrayArgumentProperties = commonCompilerArgumentsArrayProperties + listOf( K2JVMCompilerArguments::scriptTemplates, K2JVMCompilerArguments::additionalJavaModules, K2JVMCompilerArguments::scriptResolverEnvironment, @@ -201,7 +211,7 @@ class CompilerArgumentsContentProspectorTest { K2MetadataCompilerArguments::classpath, K2MetadataCompilerArguments::moduleName ) - private val k2MetadataCompilerArgumentsArrayProperties = commonCompilerArgumentsArrayArgumentProperties + listOf( + private val k2MetadataCompilerArgumentsArrayProperties = commonCompilerArgumentsArrayProperties + listOf( K2MetadataCompilerArguments::friendPaths, K2MetadataCompilerArguments::refinesPaths ) @@ -241,7 +251,10 @@ class CompilerArgumentsContentProspectorTest { K2JSCompilerArguments::includes, K2JSCompilerArguments::friendModules, K2JSCompilerArguments::errorTolerancePolicy, + K2JSCompilerArguments::irDceRuntimeDiagnostic, + K2JSCompilerArguments::repositries, ) + private val k2JSCompilerArgumentsArrayProperties = commonCompilerArgumentsArrayProperties private val k2JSDceCompilerArgumentsFlagProperties = commonToolArgumentsFlagProperties + listOf( K2JSDceArguments::devMode, @@ -255,9 +268,15 @@ class CompilerArgumentsContentProspectorTest { K2JSDceArguments::declarationsToKeep ) - private fun assertContentEquals(expect: Iterable, actual: Iterable, preprocessor: Iterable.() -> Iterable) { - (expect.count() == actual.count()) && preprocessor(expect).zip(preprocessor(actual)).all { it.first == it.second } + private fun assertContentEquals(expect: Collection>, actual: Collection>) { + //assert(expect.count() == actual.count()) { + // "Expected arguments count \"${expect.count()}\" doesn't match with actual \"${actual.count()}\"!" + //} + val processor: (Collection>) -> Collection = { el -> el.map { it.name }.sorted() } + assertEquals( + processor(expect).joinToString("\n"), + processor(actual).joinToString("\n") + ) } - } } \ No newline at end of file diff --git a/jps/jps-common/test/CompilerArgumentsSerializationTest.kt b/jps/jps-common/test/CompilerArgumentsSerializationTest.kt index 610f49256a6..135e2657f2b 100644 --- a/jps/jps-common/test/CompilerArgumentsSerializationTest.kt +++ b/jps/jps-common/test/CompilerArgumentsSerializationTest.kt @@ -6,8 +6,10 @@ import org.jetbrains.kotlin.cli.common.arguments.* import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.safeAs +import org.junit.Assert import org.junit.Test import kotlin.random.Random +import kotlin.reflect.KClass import kotlin.reflect.KMutableProperty1 import kotlin.reflect.KProperty1 import kotlin.reflect.full.memberProperties @@ -120,9 +122,25 @@ class CompilerArgumentsSerializationTest { val deserializer = CompilerArgumentsDeserializerV5(newInstance) deserializer.deserializeFrom(element) T::class.memberProperties.mapNotNull { it.safeAs>() }.forEach { - assert(it.get(oldInstance) == it.get(newInstance)) { - "Property ${it.name} has different values before (${it.get(oldInstance)}) and after (${it.get(newInstance)}) serialization" - } + val oldValue = it.get(oldInstance) + val newValue = it.get(newInstance) + if (oldValue == null && newValue == null) return@forEach + Assert.assertNotNull("Old value of property \"${it.name}\" is null but new is not", oldValue) + Assert.assertNotNull("New value of property \"${it.name}\" is null but old is not", newValue) + + if ((it.returnType.classifier as? KClass<*>)?.java?.isArray == true) + Assert.assertArrayEquals( + "Property ${it.name} has different values before (${it.get(oldInstance).toString()}) and after (${ + it.get(newInstance).toString() + }) serialization", + oldValue as Array<*>, newValue as Array<*> + ) + else + assert(it.get(oldInstance) == it.get(newInstance)) { + "Property ${it.name} has different values before (${it.get(oldInstance).toString()}) and after (${ + it.get(newInstance).toString() + }) serialization" + } } }