[JPS] Fix incremental build after changing Java constant

InlineConstantTracker implemented for tracking changed java static final constants, that used in kotlin.

#KT-46506 Fixed
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 0000000..708f481
--- /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<String, MutableSet<ConstantRef>>()
+
+    val inlineConstMap: Map<String, Collection<ConstantRef>>
+        get() = inlineConst
+
+    override fun report(filePath: String, cRefs: Collection<ConstantRef>) {
+        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 c6c3d31..90b6cac 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.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 @@
 
                 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 2f4518f..f724cce 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 @@
 
 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 {
@@ -40,6 +41,9 @@
     val EXPECT_ACTUAL_TRACKER = CompilerConfigurationKey.create<ExpectActualTracker>("expect actual tracker")
 
     @JvmField
+    val INLINE_CONST_TRACKER = CompilerConfigurationKey.create<InlineConstTracker>("inline constant tracker")
+
+    @JvmField
     val METADATA_VERSION = CompilerConfigurationKey.create<BinaryVersion>("metadata version")
 
     @JvmField
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 cc95f04..dddee83 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 @@
 
 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 @@
     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 @@
 
     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 @@
         expectActualTracker!!.report(File(expectedFilePath), File(actualFilePath))
     }
 
+    override fun inlineConstTracker_report(className: String, cRefs: Collection<ConstantRef>) {
+        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 c16c3e5..ae97a65 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
@@ -49,6 +50,9 @@
     fun hasExpectActualTracker(): Boolean
 
     @Throws(RemoteException::class)
+    fun hasInlineConstTracker(): Boolean
+
+    @Throws(RemoteException::class)
     fun hasIncrementalResultsConsumer(): Boolean
 
     @Throws(RemoteException::class)
@@ -102,6 +106,11 @@
     fun expectActualTracker_report(expectedFilePath: String, actualFilePath: String)
 
     // ---------------------------------------------------
+    // InlineConstTracker
+    @Throws(RemoteException::class)
+    fun inlineConstTracker_report(className: String, cRefs: Collection<ConstantRef>)
+
+    // ---------------------------------------------------
     // IncrementalResultsConsumer (js)
     @Throws(RemoteException::class)
     fun incrementalResultsConsumer_processHeader(headerMetadata: ByteArray)
diff --git a/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt b/compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt
index 1a25558..c9e4e55 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.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 @@
         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 0000000..5f8cd40
--- /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<ConstantRef>) {
+        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 1fb9198..41a3db0 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.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 @@
 }
 
 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 @@
                 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 0000000..0766655
--- /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<ConstantRef>)
+
+    object DoNothing : InlineConstTracker {
+        override fun report(filePath: String, cRefs: Collection<ConstantRef>) {
+        }
+    }
+}
+
+data class ConstantRef(var owner: String, var name: String, var constType: String) : Serializable