KT-6586 accessing Kotlin class static class object variable's value from Java does not properly update between compiles
#KT-6586 fixed
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
<patterns>
|
||||
<pattern testClass="org.jetbrains.kotlin.jps.build.IncrementalJpsTestGenerated" />
|
||||
<pattern testClass="org.jetbrains.kotlin.jps.build.IncrementalCacheVersionChangedTest" />
|
||||
<pattern testClass="org.jetbrains.kotlin.jps.build.IncrementalConstantSearchTest" />
|
||||
</patterns>
|
||||
<RunnerSettings RunnerId="Debug">
|
||||
<option name="DEBUG_PORT" value="" />
|
||||
|
||||
@@ -167,28 +167,26 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
|
||||
}
|
||||
|
||||
if (IncrementalCompilation.ENABLED) {
|
||||
val fileFilter = FileFilter { file ->
|
||||
KotlinSourceFileCollector.isKotlinSourceFile(file) && file !in allCompiledFiles
|
||||
}
|
||||
|
||||
when (recompilationDecision) {
|
||||
RECOMPILE_ALL_CHUNK_AND_DEPENDANTS -> {
|
||||
RECOMPILE_ALL_IN_CHUNK_AND_DEPENDANTS -> {
|
||||
allCompiledFiles.clear()
|
||||
FSOperations.markDirtyRecursively(context, chunk)
|
||||
}
|
||||
RECOMPILE_OTHERS_WITH_DEPENDANTS -> {
|
||||
RECOMPILE_OTHER_IN_CHUNK_AND_DEPENDANTS -> {
|
||||
// Workaround for IDEA 14.0-14.0.2: extended version of markDirtyRecursively is not available
|
||||
try {
|
||||
Class.forName("org.jetbrains.jps.incremental.fs.CompilationRound")
|
||||
|
||||
FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk, fileFilter)
|
||||
FSOperations.markDirtyRecursively(context, CompilationRound.NEXT, chunk, { file -> file !in allCompiledFiles })
|
||||
} catch (e: ClassNotFoundException) {
|
||||
allCompiledFiles.clear()
|
||||
FSOperations.markDirtyRecursively(context, chunk)
|
||||
}
|
||||
}
|
||||
RECOMPILE_OTHERS_IN_CHUNK -> {
|
||||
FSOperations.markDirty(context, chunk, fileFilter)
|
||||
RECOMPILE_OTHER_KOTLIN_IN_CHUNK -> {
|
||||
FSOperations.markDirty(context, chunk, { file ->
|
||||
KotlinSourceFileCollector.isKotlinSourceFile(file) && file !in allCompiledFiles
|
||||
})
|
||||
}
|
||||
}
|
||||
return ADDITIONAL_PASS_REQUIRED
|
||||
|
||||
@@ -119,9 +119,9 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
|
||||
|
||||
private fun getRecompilationDecision(protoChanged: Boolean, constantsChanged: Boolean, inlinesChanged: Boolean) =
|
||||
when {
|
||||
inlinesChanged -> RECOMPILE_ALL_CHUNK_AND_DEPENDANTS
|
||||
constantsChanged -> RECOMPILE_OTHERS_WITH_DEPENDANTS
|
||||
protoChanged -> RECOMPILE_OTHERS_IN_CHUNK
|
||||
inlinesChanged -> RECOMPILE_ALL_IN_CHUNK_AND_DEPENDANTS
|
||||
constantsChanged -> RECOMPILE_OTHER_IN_CHUNK_AND_DEPENDANTS
|
||||
protoChanged -> RECOMPILE_OTHER_KOTLIN_IN_CHUNK
|
||||
else -> DO_NOTHING
|
||||
}
|
||||
|
||||
@@ -589,9 +589,9 @@ public class IncrementalCacheImpl(targetDataRoot: File) : StorageOwner, Incremen
|
||||
|
||||
enum class RecompilationDecision {
|
||||
DO_NOTHING
|
||||
RECOMPILE_OTHERS_IN_CHUNK
|
||||
RECOMPILE_OTHERS_WITH_DEPENDANTS
|
||||
RECOMPILE_ALL_CHUNK_AND_DEPENDANTS
|
||||
RECOMPILE_OTHER_KOTLIN_IN_CHUNK
|
||||
RECOMPILE_OTHER_IN_CHUNK_AND_DEPENDANTS
|
||||
RECOMPILE_ALL_IN_CHUNK_AND_DEPENDANTS
|
||||
|
||||
fun merge(other: RecompilationDecision): RecompilationDecision {
|
||||
return if (other.ordinal() > this.ordinal()) other else this
|
||||
|
||||
@@ -44,6 +44,11 @@ import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.jps.incremental.getKotlinCache
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.PrintStream
|
||||
import org.jetbrains.jps.incremental.IncProjectBuilder
|
||||
import org.jetbrains.jps.builders.BuildResult
|
||||
import org.jetbrains.jps.incremental.BuilderRegistry
|
||||
import org.jetbrains.jps.api.CanceledStatus
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Callbacks
|
||||
|
||||
public abstract class AbstractIncrementalJpsTest : JpsBuildTestCase() {
|
||||
class object {
|
||||
@@ -70,12 +75,19 @@ public abstract class AbstractIncrementalJpsTest : JpsBuildTestCase() {
|
||||
protected open val customTest: Boolean
|
||||
get() = false
|
||||
|
||||
protected open val mockConstantSearch: Callbacks.ConstantAffectionResolver?
|
||||
get() = null
|
||||
|
||||
fun build(scope: CompileScopeTestBuilder = CompileScopeTestBuilder.make().all()): MakeResult {
|
||||
val workDirPath = FileUtil.toSystemIndependentName(workDir.getAbsolutePath())
|
||||
val logger = MyLogger(workDirPath)
|
||||
val descriptor = createProjectDescriptor(BuildLoggingManager(logger))
|
||||
try {
|
||||
val buildResult = doBuild(descriptor, scope)!!
|
||||
val builder = IncProjectBuilder(descriptor, BuilderRegistry.getInstance(), myBuildParams, CanceledStatus.NULL, mockConstantSearch, true)
|
||||
val buildResult = BuildResult()
|
||||
builder.addMessageHandler(buildResult)
|
||||
builder.build(scope.build(), false)
|
||||
|
||||
if (!buildResult.isSuccessful()) {
|
||||
val errorMessages =
|
||||
buildResult
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Callbacks
|
||||
import com.intellij.util.concurrency.FixedFuture
|
||||
import java.io.File
|
||||
import java.util.concurrent.Future
|
||||
|
||||
public class IncrementalConstantSearchTest : AbstractIncrementalJpsTest() {
|
||||
fun testJavaConstantChangedUsedInKotlin() {
|
||||
doTest("jps-plugin/testData/incremental/custom/javaConstantChangedUsedInKotlin/")
|
||||
}
|
||||
|
||||
fun testJavaConstantUnchangedUsedInKotlin() {
|
||||
doTest("jps-plugin/testData/incremental/custom/javaConstantUnchangedUsedInKotlin/")
|
||||
}
|
||||
|
||||
fun testKotlinConstantChangedUsedInJava() {
|
||||
doTest("jps-plugin/testData/incremental/custom/kotlinConstantChangedUsedInJava/")
|
||||
}
|
||||
|
||||
fun testKotlinConstantUnchangedUsedInJava() {
|
||||
doTest("jps-plugin/testData/incremental/custom/kotlinConstantUnchangedUsedInJava/")
|
||||
}
|
||||
|
||||
override val mockConstantSearch: Callbacks.ConstantAffectionResolver?
|
||||
get() = object : Callbacks.ConstantAffectionResolver {
|
||||
override fun request(
|
||||
ownerClassName: String?,
|
||||
fieldName: String?,
|
||||
accessFlags: Int,
|
||||
fieldRemoved: Boolean,
|
||||
accessChanged: Boolean
|
||||
): Future<Callbacks.ConstantAffection> {
|
||||
// We emulate how constant affection service works in IDEA:
|
||||
// it is able to find Kotlin usages of Java constant, but can't find Java usages of Kotlin constant
|
||||
val affectedFiles = if (ownerClassName == "JavaClass" && fieldName == "CONST") {
|
||||
listOf(File(workDir, "src/usage.kt"))
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
return FixedFuture(Callbacks.ConstantAffection(affectedFiles))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
public class JavaClass {
|
||||
public static final String CONST = "A";
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
public class JavaClass {
|
||||
public static final String CONST = "B";
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
Cleaning output files:
|
||||
out/production/module/JavaClass.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/JavaClass.java
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/Usage.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/usage.kt
|
||||
End of files
|
||||
@@ -0,0 +1,2 @@
|
||||
deprecated(JavaClass.CONST + JavaClass.CONST)
|
||||
class Usage
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
public class JavaClass {
|
||||
public static final String CONST = "A";
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
public class JavaClass {
|
||||
public static final String CONST = "A";
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
Cleaning output files:
|
||||
out/production/module/JavaClass.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/JavaClass.java
|
||||
End of files
|
||||
@@ -0,0 +1,2 @@
|
||||
deprecated(JavaClass.CONST + JavaClass.CONST)
|
||||
class Usage
|
||||
@@ -0,0 +1,7 @@
|
||||
import test.*;
|
||||
|
||||
class Usage {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(Klass.CONST + Klass.CONST);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
Cleaning output files:
|
||||
out/production/module/test/Klass$Default.class
|
||||
out/production/module/test/Klass.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/const.kt
|
||||
End of files
|
||||
Compiling files:
|
||||
src/Usage.java
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/module/Usage.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/Usage.java
|
||||
End of files
|
||||
@@ -0,0 +1,8 @@
|
||||
package test
|
||||
|
||||
class Klass {
|
||||
class object {
|
||||
// Old and new constant values are different, but their hashes are the same
|
||||
val CONST = "BF"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package test
|
||||
|
||||
class Klass {
|
||||
class object {
|
||||
// Old and new constant values are different, but their hashes are the same
|
||||
val CONST = "Ae"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import test.*;
|
||||
|
||||
class Usage {
|
||||
public static void main(String[] args) {
|
||||
System.out.println(Klass.CONST + Klass.CONST);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
Cleaning output files:
|
||||
out/production/module/test/Klass$Default.class
|
||||
out/production/module/test/Klass.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/const.kt
|
||||
End of files
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
class Klass {
|
||||
class object {
|
||||
val CONST = "bar"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
class Klass {
|
||||
class object {
|
||||
val CONST = "bar"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user