[JPS] Fix incremental build after changing Java enum used in Kotlin when

EnumWhenTracker implemented for tracking changed java enum class items, that used in kotlin when expression.

#KT-47824 Fixed
This commit is contained in:
Aleksei.Cherepanov
2021-11-04 17:13:56 +03:00
committed by Space
parent ee8de63497
commit 3d8f140d6b
38 changed files with 319 additions and 57 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.daemon.client.CompilerCallbackServicesFacadeServer
import org.jetbrains.kotlin.daemon.client.reportFromDaemon
import org.jetbrains.kotlin.daemon.common.JpsCompilerServicesFacade
import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -38,6 +39,7 @@ internal class JpsCompilerServicesFacadeImpl(
env.services[CompilationCanceledStatus::class.java],
env.services[ExpectActualTracker::class.java],
env.services[InlineConstTracker::class.java],
env.services[EnumWhenTracker::class.java],
env.services[IncrementalResultsConsumer::class.java],
env.services[IncrementalDataProvider::class.java],
port
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.incremental.*
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.build.report.ICReporterBase
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.jps.KotlinJpsBundle
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
@@ -236,6 +237,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
LookupTracker.DO_NOTHING,
ExpectActualTracker.DoNothing,
InlineConstTracker.DoNothing,
EnumWhenTracker.DoNothing,
chunk,
messageCollector
) ?: return
@@ -356,7 +358,10 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
if (!kotlinChunk.haveSameCompiler) {
messageCollector.report(
ERROR,
KotlinJpsBundle.message("error.text.cyclically.dependent.modules.0.should.have.same.compiler", kotlinChunk.presentableModulesToCompilersList)
KotlinJpsBundle.message(
"error.text.cyclically.dependent.modules.0.should.have.same.compiler",
kotlinChunk.presentableModulesToCompilersList
)
)
return ABORT
}
@@ -394,8 +399,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val targetsWithoutOutputDir = targets.filter { it.outputDir == null }
if (targetsWithoutOutputDir.isNotEmpty()) {
messageCollector.report(ERROR,
KotlinJpsBundle.message("error.text.output.directory.not.specified.for.0", targetsWithoutOutputDir.joinToString())
messageCollector.report(
ERROR,
KotlinJpsBundle.message("error.text.output.directory.not.specified.for.0", targetsWithoutOutputDir.joinToString())
)
return ABORT
}
@@ -405,6 +411,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val exceptActualTracer = ExpectActualTrackerImpl()
val incrementalCaches = kotlinChunk.loadCaches()
val inlineConstTracker = InlineConstTrackerImpl()
val enumWhenTracker = EnumWhenTrackerImpl()
val environment = createCompileEnvironment(
context,
representativeTarget,
@@ -412,6 +419,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
lookupTracker,
exceptActualTracer,
inlineConstTracker,
enumWhenTracker,
chunk,
messageCollector
) ?: return ABORT
@@ -604,11 +612,19 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
lookupTracker: LookupTracker,
exceptActualTracer: ExpectActualTracker,
inlineConstTracker: InlineConstTracker,
enumWhenTracker: EnumWhenTracker,
chunk: ModuleChunk,
messageCollector: MessageCollectorAdapter
): JpsCompilerEnvironment? {
val compilerServices = with(Services.Builder()) {
kotlinModuleBuilderTarget.makeServices(this, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker)
kotlinModuleBuilderTarget.makeServices(
this,
incrementalCaches,
lookupTracker,
exceptActualTracer,
inlineConstTracker,
enumWhenTracker
)
build()
}
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.ChangesCollector
import org.jetbrains.kotlin.incremental.IncrementalJsCache
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -70,9 +71,10 @@ class KotlinJsModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleBu
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>,
lookupTracker: LookupTracker,
exceptActualTracer: ExpectActualTracker,
inlineConstTracker: InlineConstTracker
inlineConstTracker: InlineConstTracker,
enumWhenTracker: EnumWhenTracker
) {
super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker)
super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker, enumWhenTracker)
with(builder) {
register(IncrementalResultsConsumer::class.java, IncrementalResultsConsumerImpl())
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.*
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -80,9 +81,10 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>,
lookupTracker: LookupTracker,
exceptActualTracer: ExpectActualTracker,
inlineConstTracker: InlineConstTracker
inlineConstTracker: InlineConstTracker,
enumWhenTracker: EnumWhenTracker
) {
super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker)
super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer, inlineConstTracker, enumWhenTracker)
with(builder) {
register(
@@ -363,6 +365,7 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB
val previousMappings = localContext.projectDescriptor.dataManager.mappings
val callback = JavaBuilderUtil.getDependenciesRegistrar(localContext)
val inlineConstTracker = environment.services[InlineConstTracker::class.java] as InlineConstTrackerImpl
val enumWhenTracker = environment.services[EnumWhenTracker::class.java] as EnumWhenTrackerImpl
val targetDirtyFiles: Map<ModuleBuildTarget, Set<File>> = chunk.targets.keysToMap {
val files = HashSet<File>()
@@ -393,24 +396,8 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB
// process inlineConstTracker
for (sourceFile: File in sourceFiles) {
val cRefs = inlineConstTracker.inlineConstMap[sourceFile.path]?.mapNotNull { cRef: ConstantRef ->
val descriptor = when (cRef.constType) {
"Byte" -> "B"
"Short" -> "S"
"Int" -> "I"
"Long" -> "J"
"Float" -> "F"
"Double" -> "D"
"Boolean" -> "Z"
"Char" -> "C"
"String" -> "Ljava/lang/String;"
else -> null
} ?: return@mapNotNull null
Callbacks.createConstantReference(cRef.owner, cRef.name, descriptor)
} ?: continue
val className = output.outputClass.className.internalName
callback.registerConstantReferences(className, cRefs)
processInlineConstTracker(inlineConstTracker, sourceFile, output, callback)
processEnumWhenTracker(enumWhenTracker, sourceFile, output, callback)
}
callback.associate(
@@ -425,4 +412,30 @@ class KotlinJvmModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleB
JavaBuilderUtil.registerFilesToCompile(localContext, allCompiled)
JavaBuilderUtil.registerSuccessfullyCompiled(localContext, allCompiled)
}
private fun processInlineConstTracker(inlineConstTracker: InlineConstTrackerImpl, sourceFile: File, output: GeneratedJvmClass, callback: Callbacks.Backend) {
val cRefs = inlineConstTracker.inlineConstMap[sourceFile.path]?.mapNotNull { cRef: ConstantRef ->
val descriptor = when (cRef.constType) {
"Byte" -> "B"
"Short" -> "S"
"Int" -> "I"
"Long" -> "J"
"Float" -> "F"
"Double" -> "D"
"Boolean" -> "Z"
"Char" -> "C"
"String" -> "Ljava/lang/String;"
else -> null
} ?: return@mapNotNull null
Callbacks.createConstantReference(cRef.owner, cRef.name, descriptor)
} ?: return
val className = output.outputClass.className.internalName
callback.registerConstantReferences(className, cRefs)
}
private fun processEnumWhenTracker(enumWhenTracker: EnumWhenTrackerImpl, sourceFile: File, output: GeneratedJvmClass, callback: Callbacks.Backend) {
val enumFqNameClasses = enumWhenTracker.whenExpressionFilePathToEnumClassMap[sourceFile.path]?.map { "$it.*" } ?: return
callback.registerImports(output.outputClass.className.internalName, listOf(), enumFqNameClasses)
}
}
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.incremental.ChangesCollector
import org.jetbrains.kotlin.incremental.ExpectActualTrackerImpl
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.InlineConstTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -272,7 +273,8 @@ abstract class KotlinModuleBuildTarget<BuildMetaInfoType : BuildMetaInfo> intern
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>,
lookupTracker: LookupTracker,
exceptActualTracer: ExpectActualTracker,
inlineConstTracker: InlineConstTracker
inlineConstTracker: InlineConstTracker,
enumWhenTracker: EnumWhenTracker
) {
with(builder) {
register(LookupTracker::class.java, lookupTracker)
@@ -283,6 +285,7 @@ abstract class KotlinModuleBuildTarget<BuildMetaInfoType : BuildMetaInfo> intern
}
})
register(InlineConstTracker::class.java, inlineConstTracker)
register(EnumWhenTracker::class.java, enumWhenTracker)
}
}
@@ -8,9 +8,6 @@ Exit code: NOTHING_DONE
Compiling files:
src/Enum.java
End of files
================ Step #2 =================
Cleaning output files:
out/production/module/META-INF/module.kotlin_module
out/production/module/UseKt$WhenMappings.class
@@ -19,5 +16,21 @@ End of files
Compiling files:
src/use.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
'when' expression must be exhaustive, add necessary 'C' branch or 'else' branch instead
================ Step #2 =================
Cleaning output files:
out/production/module/Enum.class
End of files
Compiling files:
src/use.kt
End of files
Exit code: OK
------------------------------------------
Compiling files:
src/Enum.java
End of files