diff --git a/build-common/src/org/jetbrains/kotlin/incremental/KotlinClassInfo.kt b/build-common/src/org/jetbrains/kotlin/incremental/KotlinClassInfo.kt index 746300b280af5..f21f8c40f4814 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/KotlinClassInfo.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/KotlinClassInfo.kt @@ -180,7 +180,7 @@ private fun getExtraInfo(classHeader: KotlinClassHeader, classContents: ByteArra val constantSnapshots: Map = classNode.fields.associate { fieldNode -> // Note: `fieldNode` is a constant because we kept only fields that are (non-private) constants in `classNode` - fieldNode.name to (fieldNode.value?.let { ConstantValueExternalizer.toByteArray(it).hashToLong() } ?: 0L) + fieldNode.name to ConstantValueExternalizer.toByteArray(fieldNode.value!!).hashToLong() } val inlineFunctionOrAccessorSnapshots: Map = classNode.methods.associate { methodNode -> @@ -210,7 +210,11 @@ class SelectiveClassVisitor( ) : ClassVisitor(Opcodes.API_VERSION, cv) { override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? { - return if (shouldVisitField(JvmMemberSignature.Field(name, desc), access.isPrivate(), access.isStaticFinal())) { + // Note: A constant's value must be not-null. A static final field with a `null` value at the bytecode declaration is not a constant + // (whether the value is initialized later in the static initializer or not, it won't be inlined by the compiler). + val isConstant = access.isStaticFinal() && value != null + + return if (shouldVisitField(JvmMemberSignature.Field(name, desc), access.isPrivate(), isConstant)) { cv.visitField(access, name, desc, signature, value) } else null } diff --git a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest.kt b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest.kt index 7918ee5baf4d6..ac8a9c5c859d7 100644 --- a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest.kt +++ b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest.kt @@ -290,6 +290,19 @@ class KotlinOnlyClasspathChangesComputerTest : ClasspathChangesComputerTest() { ).assertEquals(changes) } + /** Regression test for KT-58986.*/ + @Test + fun testDelegatedProperties() { + // Check that classpath changes computation doesn't fail + val changes = computeClasspathChanges(File(testDataDir, "KotlinOnly/testDelegatedProperties/src"), tmpDir) + Changes( + lookupSymbols = setOf( + LookupSymbol(name = "delegatedProperty", scope = "com.example"), + ), + fqNames = setOf("com.example") + ).assertEquals(changes) + } + /** Tests [SupertypesInheritorsImpact]. */ @Test override fun testImpactComputation_SupertypesInheritors() { diff --git a/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/classes/current-classpath/com/example/Delegate.class b/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/classes/current-classpath/com/example/Delegate.class new file mode 100644 index 0000000000000..56e95dc0b03a6 Binary files /dev/null and b/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/classes/current-classpath/com/example/Delegate.class differ diff --git a/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/classes/current-classpath/com/example/FileFacadeKt.class b/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/classes/current-classpath/com/example/FileFacadeKt.class new file mode 100644 index 0000000000000..861a3ff0d4e24 Binary files /dev/null and b/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/classes/current-classpath/com/example/FileFacadeKt.class differ diff --git a/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/classes/previous-classpath/com/example/Delegate.class b/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/classes/previous-classpath/com/example/Delegate.class new file mode 100644 index 0000000000000..e4f0529c480d7 Binary files /dev/null and b/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/classes/previous-classpath/com/example/Delegate.class differ diff --git a/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/src/current-classpath/com/example/FileFacade.kt b/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/src/current-classpath/com/example/FileFacade.kt new file mode 100644 index 0000000000000..693405e9dfd20 --- /dev/null +++ b/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/src/current-classpath/com/example/FileFacade.kt @@ -0,0 +1,15 @@ +package com.example + +import kotlin.reflect.KProperty + +var delegatedProperty: String by Delegate() // Added + +class Delegate { + + operator fun getValue(thisRef: Any?, property: KProperty<*>): String { + return "" + } + + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { + } +} \ No newline at end of file diff --git a/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/src/previous-classpath/com/example/FileFacade.kt b/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/src/previous-classpath/com/example/FileFacade.kt new file mode 100644 index 0000000000000..f5ec705b72ae3 --- /dev/null +++ b/compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/src/previous-classpath/com/example/FileFacade.kt @@ -0,0 +1,13 @@ +package com.example + +import kotlin.reflect.KProperty + +class Delegate { + + operator fun getValue(thisRef: Any?, property: KProperty<*>): String { + return "" + } + + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { + } +} \ No newline at end of file