From cc5382b37ed99164a5efaebb3a26771e95419968 Mon Sep 17 00:00:00 2001 From: "Aleksei.Cherepanov" Date: Thu, 2 Sep 2021 12:32:30 +0300 Subject: [PATCH] [JPS] Fix incremental build after changing Java constant InlineConstantTracker implemented for tracking changed java static final constants, that used in kotlin. #KT-46506 Fixed --- .../incremental/InlineConstTrackerImpl.kt | 20 ++++++++++ .../jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt | 3 ++ .../kotlin/config/CommonConfigurationKeys.kt | 4 ++ .../CompilerCallbackServicesFacadeServer.kt | 9 +++++ .../common/CompilerCallbackServicesFacade.kt | 9 +++++ .../kotlin/daemon/CompileServiceImpl.kt | 4 ++ .../kotlin/daemon/RemoteInlineConstTracker.kt | 23 +++++++++++ .../kotlin/backend/jvm/lower/ConstLowering.kt | 39 ++++++++++++++++++- .../components/InlineConstTracker.kt | 16 ++++++++ 9 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 build-common/src/org/jetbrains/kotlin/incremental/InlineConstTrackerImpl.kt create mode 100644 compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteInlineConstTracker.kt create mode 100644 core/compiler.common/src/org/jetbrains/kotlin/incremental/components/InlineConstTracker.kt diff --git a/build-common/src/org/jetbrains/kotlin/incremental/InlineConstTrackerImpl.kt b/build-common/src/org/jetbrains/kotlin/incremental/InlineConstTrackerImpl.kt new file mode 100644 index 00000000000..708f4815ebe --- /dev/null +++ b/build-common/src/org/jetbrains/kotlin/incremental/InlineConstTrackerImpl.kt @@ -0,0 +1,20 @@ +/* + * 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.kotlin.incremental + +import org.jetbrains.kotlin.incremental.components.InlineConstTracker +import org.jetbrains.kotlin.incremental.components.ConstantRef + +class InlineConstTrackerImpl : InlineConstTracker { + private val inlineConst = hashMapOf>() + + val inlineConstMap: Map> + get() = inlineConst + + override fun report(filePath: String, cRefs: Collection) { + inlineConst.getOrPut(filePath) { hashSetOf() }.addAll(cRefs) + } +} \ No newline at end of file diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt index c6c3d314130..90b6cac9055 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -41,6 +41,7 @@ import org.jetbrains.kotlin.codegen.CompilationException import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.incremental.components.InlineConstTracker import org.jetbrains.kotlin.load.java.JavaClassesTracker import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion @@ -244,6 +245,8 @@ class K2JVMCompiler : CLICompiler() { putIfNotNull(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER, services[ExpectActualTracker::class.java]) + putIfNotNull(CommonConfigurationKeys.INLINE_CONST_TRACKER, services[InlineConstTracker::class.java]) + putIfNotNull( JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS, services[IncrementalCompilationComponents::class.java] diff --git a/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt b/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt index 2f4518f87f5..f724ccec2ac 100644 --- a/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt +++ b/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.config import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.incremental.components.InlineConstTracker import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion object CommonConfigurationKeys { @@ -39,6 +40,9 @@ object CommonConfigurationKeys { @JvmField val EXPECT_ACTUAL_TRACKER = CompilerConfigurationKey.create("expect actual tracker") + @JvmField + val INLINE_CONST_TRACKER = CompilerConfigurationKey.create("inline constant tracker") + @JvmField val METADATA_VERSION = CompilerConfigurationKey.create("metadata version") diff --git a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/CompilerCallbackServicesFacadeServer.kt b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/CompilerCallbackServicesFacadeServer.kt index cc95f04f392..dddee83cb25 100644 --- a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/CompilerCallbackServicesFacadeServer.kt +++ b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/CompilerCallbackServicesFacadeServer.kt @@ -18,6 +18,8 @@ package org.jetbrains.kotlin.daemon.client import org.jetbrains.kotlin.daemon.common.* import org.jetbrains.kotlin.incremental.components.ExpectActualTracker +import org.jetbrains.kotlin.incremental.components.InlineConstTracker +import org.jetbrains.kotlin.incremental.components.ConstantRef import org.jetbrains.kotlin.incremental.components.LookupInfo import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider @@ -36,6 +38,7 @@ open class CompilerCallbackServicesFacadeServer( val lookupTracker: LookupTracker? = null, val compilationCanceledStatus: CompilationCanceledStatus? = null, val expectActualTracker: ExpectActualTracker? = null, + val inlineConstTracker: InlineConstTracker? = null, val incrementalResultsConsumer: IncrementalResultsConsumer? = null, val incrementalDataProvider: IncrementalDataProvider? = null, port: Int = SOCKET_ANY_FREE_PORT @@ -53,6 +56,8 @@ open class CompilerCallbackServicesFacadeServer( override fun hasExpectActualTracker(): Boolean = expectActualTracker != null + override fun hasInlineConstTracker(): Boolean = inlineConstTracker != null + override fun hasIncrementalResultsConsumer(): Boolean = incrementalResultsConsumer != null override fun hasIncrementalDataProvider(): Boolean = incrementalDataProvider != null @@ -116,6 +121,10 @@ open class CompilerCallbackServicesFacadeServer( expectActualTracker!!.report(File(expectedFilePath), File(actualFilePath)) } + override fun inlineConstTracker_report(className: String, cRefs: Collection) { + inlineConstTracker?.report(className, cRefs) ?: throw NullPointerException("inlineConstTracker was not initialized") + } + override fun incrementalResultsConsumer_processHeader(headerMetadata: ByteArray) { incrementalResultsConsumer!!.processHeader(headerMetadata) } diff --git a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilerCallbackServicesFacade.kt b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilerCallbackServicesFacade.kt index c16c3e5e3c8..ae97a65fbc1 100644 --- a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilerCallbackServicesFacade.kt +++ b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompilerCallbackServicesFacade.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.daemon.common import org.jetbrains.kotlin.incremental.components.LookupInfo +import org.jetbrains.kotlin.incremental.components.ConstantRef import org.jetbrains.kotlin.incremental.js.JsInlineFunctionHash import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto import org.jetbrains.kotlin.modules.TargetId @@ -48,6 +49,9 @@ interface CompilerCallbackServicesFacade : Remote { @Throws(RemoteException::class) fun hasExpectActualTracker(): Boolean + @Throws(RemoteException::class) + fun hasInlineConstTracker(): Boolean + @Throws(RemoteException::class) fun hasIncrementalResultsConsumer(): Boolean @@ -101,6 +105,11 @@ interface CompilerCallbackServicesFacade : Remote { @Throws(RemoteException::class) fun expectActualTracker_report(expectedFilePath: String, actualFilePath: String) + // --------------------------------------------------- + // InlineConstTracker + @Throws(RemoteException::class) + fun inlineConstTracker_report(className: String, cRefs: Collection) + // --------------------------------------------------- // IncrementalResultsConsumer (js) @Throws(RemoteException::class) diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt index 1a25558a111..c9e4e558398 100644 --- a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt +++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt @@ -47,6 +47,7 @@ import org.jetbrains.kotlin.daemon.report.getBuildReporter import org.jetbrains.kotlin.incremental.* import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.incremental.components.InlineConstTracker import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer import org.jetbrains.kotlin.incremental.multiproject.ModulesApiHistoryAndroid @@ -873,6 +874,9 @@ class CompileServiceImpl( if (facade.hasExpectActualTracker()) { builder.register(ExpectActualTracker::class.java, RemoteExpectActualTracker(facade, rpcProfiler)) } + if (facade.hasInlineConstTracker()) { + builder.register(InlineConstTracker::class.java, RemoteInlineConstTracker(facade, rpcProfiler)) + } if (facade.hasIncrementalResultsConsumer()) { builder.register(IncrementalResultsConsumer::class.java, RemoteIncrementalResultsConsumer(facade, eventManager, rpcProfiler)) } diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteInlineConstTracker.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteInlineConstTracker.kt new file mode 100644 index 00000000000..5f8cd40b98f --- /dev/null +++ b/compiler/daemon/src/org/jetbrains/kotlin/daemon/RemoteInlineConstTracker.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2018 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.kotlin.daemon + +import org.jetbrains.kotlin.daemon.common.DummyProfiler +import org.jetbrains.kotlin.daemon.common.Profiler +import org.jetbrains.kotlin.daemon.common.withMeasure +import org.jetbrains.kotlin.incremental.components.InlineConstTracker +import org.jetbrains.kotlin.incremental.components.ConstantRef + +class RemoteInlineConstTracker( + @Suppress("DEPRECATION") val facade: org.jetbrains.kotlin.daemon.common.CompilerCallbackServicesFacade, + val profiler: Profiler = DummyProfiler() +): InlineConstTracker { + override fun report(filePath: String, cRefs: Collection) { + profiler.withMeasure(this) { + facade.inlineConstTracker_report(filePath, cRefs) + } + } +} \ No newline at end of file diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ConstLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ConstLowering.kt index 1fb919861df..41a3db0f211 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ConstLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ConstLowering.kt @@ -19,6 +19,14 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl import org.jetbrains.kotlin.ir.types.isPrimitiveType import org.jetbrains.kotlin.ir.types.isStringClassType import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid +import org.jetbrains.kotlin.incremental.components.InlineConstTracker +import org.jetbrains.kotlin.incremental.components.ConstantRef +import org.jetbrains.kotlin.config.CommonConfigurationKeys +import org.jetbrains.kotlin.descriptors.SourceFile +import org.jetbrains.kotlin.ir.descriptors.toIrBasedDescriptor +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.ir.util.IdSignature +import org.jetbrains.kotlin.load.kotlin.toSourceElement internal val constPhase1 = makeIrFilePhase( ::ConstLowering, @@ -48,11 +56,16 @@ fun IrField.constantValue(context: JvmBackendContext? = null): IrConst<*>? { } class ConstLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), FileLoweringPass { + val inlineConstTracker = + context.state.configuration[CommonConfigurationKeys.INLINE_CONST_TRACKER] ?: InlineConstTracker.DoNothing + override fun lower(irFile: IrFile) = irFile.transformChildrenVoid() private fun IrExpression.lowerConstRead(receiver: IrExpression?, field: IrField?): IrExpression? { val value = field?.constantValue() ?: return null transformChildrenVoid() + reportInlineConst(this@lowerConstRead, field) + val resultExpression = if (context.state.shouldInlineConstVals) value.copyWithOffsets(startOffset, endOffset) else @@ -66,7 +79,31 @@ class ConstLowering(val context: JvmBackendContext) : IrElementTransformerVoid() listOf(receiver, resultExpression) ) } - + + private fun reportInlineConst(irExpression: IrExpression, field: IrField?) { + if (inlineConstTracker == InlineConstTracker.DoNothing) return + val value = field?.constantValue() ?: return + + if (!field.isFinal || !field.isStatic) return + + val sourceFile = field.toIrBasedDescriptor().containingDeclaration.toSourceElement.containingFile + if (sourceFile == SourceFile.NO_SOURCE_FILE || sourceFile.toString().lowercase().endsWith(".kt")) return + + for (file: KtFile in context.state.files) { + val fileName = file.virtualFilePath + val owner = + ((irExpression as? IrGetFieldImpl)?.symbol?.signature as? IdSignature.CompositeSignature)?.container?.asPublic()?.firstNameSegment + ?: continue + val name = field.name.asString() + val constType = value.kind.toString() + + inlineConstTracker.report( + fileName, + listOf(ConstantRef(owner, name, constType)) + ) + } + } + private fun IrExpression.shouldDropConstReceiver() = this is IrConst<*> || this is IrGetValue || this is IrGetObjectValue diff --git a/core/compiler.common/src/org/jetbrains/kotlin/incremental/components/InlineConstTracker.kt b/core/compiler.common/src/org/jetbrains/kotlin/incremental/components/InlineConstTracker.kt new file mode 100644 index 00000000000..0766655fa98 --- /dev/null +++ b/core/compiler.common/src/org/jetbrains/kotlin/incremental/components/InlineConstTracker.kt @@ -0,0 +1,16 @@ +package org.jetbrains.kotlin.incremental.components + +import org.jetbrains.kotlin.container.DefaultImplementation +import java.io.Serializable + +@DefaultImplementation(InlineConstTracker.DoNothing::class) +interface InlineConstTracker { + fun report(filePath: String, cRefs: Collection) + + object DoNothing : InlineConstTracker { + override fun report(filePath: String, cRefs: Collection) { + } + } +} + +data class ConstantRef(var owner: String, var name: String, var constType: String) : Serializable