[Compiler CLI] Sort flags and features before appending them to string

JS IR BE incremental compilation infrastructure uses
 LanguageVersionSettings::toString method to detect if any
 compiler features or flags were enabled or disabled.
 It is important that the features and flags order are stable
 in the result string.

^KT-56580 Fixed
This commit is contained in:
Alexander Korepanov
2023-02-14 12:38:56 +01:00
committed by Space Team
parent df450ac43c
commit 43cef114c6
9 changed files with 69 additions and 2 deletions
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.backend.js.ic
import org.jetbrains.kotlin.backend.common.serialization.Hash128Bits
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.KotlinCompilerVersion
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.CrossModuleReferences
import org.jetbrains.kotlin.ir.IrElement
@@ -87,6 +88,8 @@ internal class ICHasher {
private val hashCalculator = HashCalculatorForIC()
fun calculateConfigHash(config: CompilerConfiguration): ICHash {
hashCalculator.update(KotlinCompilerVersion.VERSION)
val importantSettings = listOf(
JSConfigurationKeys.GENERATE_DTS,
JSConfigurationKeys.MODULE_KIND,
@@ -538,7 +538,7 @@ class LanguageVersionSettingsImpl @JvmOverloads constructor(
override fun toString() = buildString {
append("Language = $languageVersion, API = $apiVersion")
specificFeatures.forEach { (feature, state) ->
specificFeatures.entries.sortedBy { (feature, _) -> feature.ordinal }.forEach { (feature, state) ->
val char = when (state) {
LanguageFeature.State.ENABLED -> '+'
LanguageFeature.State.ENABLED_WITH_WARNING -> '~'
@@ -546,7 +546,7 @@ class LanguageVersionSettingsImpl @JvmOverloads constructor(
}
append(" $char$feature")
}
analysisFlags.forEach { (flag, value) ->
analysisFlags.entries.sortedBy { (flag, _) -> flag.toString() }.forEach { (flag, value) ->
append(" $flag:$value")
}
}
@@ -255,6 +255,11 @@ public class JsIrES6InvalidationTestGenerated extends AbstractJsIrES6Invalidatio
runTest("js/js.translator/testData/incremental/invalidation/jsModuleAnnotation/");
}
@TestMetadata("languageVersionSettings")
public void testLanguageVersionSettings() throws Exception {
runTest("js/js.translator/testData/incremental/invalidation/languageVersionSettings/");
}
@TestMetadata("localInlineFunction")
public void testLocalInlineFunction() throws Exception {
runTest("js/js.translator/testData/incremental/invalidation/localInlineFunction/");
@@ -255,6 +255,11 @@ public class JsIrInvalidationTestGenerated extends AbstractJsIrInvalidationTest
runTest("js/js.translator/testData/incremental/invalidation/jsModuleAnnotation/");
}
@TestMetadata("languageVersionSettings")
public void testLanguageVersionSettings() throws Exception {
runTest("js/js.translator/testData/incremental/invalidation/languageVersionSettings/");
}
@TestMetadata("localInlineFunction")
public void testLocalInlineFunction() throws Exception {
runTest("js/js.translator/testData/incremental/invalidation/localInlineFunction/");
@@ -0,0 +1 @@
fun demo() = 42
@@ -0,0 +1,6 @@
STEP 0..3:
added file: l1.kt
STEP 4..5:
STEP 6:
added file: l1.kt
STEP 7:
@@ -0,0 +1,7 @@
fun box(stepId: Int): String {
when (stepId) {
in 0..7 -> if (demo() != 42) return "Fail"
else -> return "Unknown"
}
return "OK"
}
@@ -0,0 +1,10 @@
STEP 0..3:
dependencies: lib1
added file: m.kt
STEP 4..5:
dependencies: lib1
STEP 6:
dependencies: lib1
added file: m.kt
STEP 7:
dependencies: lib1
@@ -0,0 +1,30 @@
MODULES: lib1, main
STEP 0:
libs: lib1, main
dirty js: lib1, main
STEP 1:
language: +TypeAliases
libs: lib1, main
dirty js: lib1, main
STEP 2:
language: +TypeAliases, +BoundCallableReferences, +LocalDelegatedProperties, +TopLevelSealedInheritance
libs: lib1, main
dirty js: lib1, main
STEP 3:
language: +TypeAliases, +BoundCallableReferences, +TopLevelSealedInheritance
libs: lib1, main
dirty js: lib1, main
STEP 4:
language: +BoundCallableReferences, +TopLevelSealedInheritance, +TypeAliases
libs: lib1, main
STEP 5:
language: +BoundCallableReferences, +TypeAliases, +TopLevelSealedInheritance
libs: lib1, main
STEP 6:
language: +BoundCallableReferences, -TypeAliases, +TopLevelSealedInheritance
libs: lib1, main
dirty js: lib1, main
STEP 7:
language: +TopLevelSealedInheritance, +BoundCallableReferences, +TypeAliases
libs: lib1, main