From 078356164bf8c773677e62d7f9dbba9ca41c431e Mon Sep 17 00:00:00 2001 From: Hung Nguyen Date: Fri, 16 Jun 2023 15:28:39 +0100 Subject: [PATCH] IC: Fix regression in detecting constants in KotlinClassInfo.kt A constant is a static final field with non-null value. In a previous commit (0b09be7), we accidentally removed the *non-null value* filter when looking for constants in the bytecode. This commit re-adds that filter to make sure the detection is correct. Test: Added KotlinOnlyClasspathChangesComputerTest.testDelegatedProperties ^KT-58986: Fixed --- .../kotlin/incremental/KotlinClassInfo.kt | 8 ++++++-- .../ClasspathChangesComputerTest.kt | 13 +++++++++++++ .../current-classpath/com/example/Delegate.class | Bin 0 -> 1529 bytes .../com/example/FileFacadeKt.class | Bin 0 -> 1871 bytes .../com/example/Delegate.class | Bin 0 -> 1529 bytes .../current-classpath/com/example/FileFacade.kt | 15 +++++++++++++++ .../previous-classpath/com/example/FileFacade.kt | 13 +++++++++++++ 7 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/classes/current-classpath/com/example/Delegate.class create mode 100644 compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/classes/current-classpath/com/example/FileFacadeKt.class create mode 100644 compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/classes/previous-classpath/com/example/Delegate.class create mode 100644 compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/src/current-classpath/com/example/FileFacade.kt create mode 100644 compiler/incremental-compilation-impl/testData/org/jetbrains/kotlin/incremental/classpathDiff/ClasspathChangesComputerTest/KotlinOnly/testDelegatedProperties/src/previous-classpath/com/example/FileFacade.kt diff --git a/build-common/src/org/jetbrains/kotlin/incremental/KotlinClassInfo.kt b/build-common/src/org/jetbrains/kotlin/incremental/KotlinClassInfo.kt index 746300b280a..f21f8c40f48 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 7918ee5baf4..ac8a9c5c859 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 0000000000000000000000000000000000000000..56e95dc0b03a617dd181cbb1013e71a38db74e33 GIT binary patch literal 1529 zcmb7ETTc@~7(KJSZ5IklLBt}6f^revQm+Ywh#0h3k%02T)6kA(V7p6pr;Wbhi$BC) zpidef4B^oqW&EaH3TQR4Nq4^a_RKloZRf|&Z{Gpj#Y2XHvR`w=TV6YGh4VzXqRN#> zfic*7yulrpdsXM<&Ymc%6k-g?1?fq($Pk;F-s(mINegkL7~*PIh75zHPK5IeW>u&y z?$!mvqp8yG-1DV6GmD*B#!G%s zb@qhX3Apq^hkKr{xRO5EYra~myDn)>{0l`8zT*m=;6W6z37cUw%4e@pbEKz4;BnU} zdOH44mctaX3>V6~qP!mot@D7_1OXW)J0*8ov8V{T`~$dPp&x?`T?;48t1OxrVo2$J zY=}1u*)s)fb&{gZ{k`CnO4#nzQm0t{+N(24?I;=2x z*2~b*VZq3=$BE;QN%E{-v12(SA1|18A{QTGc~-FOWGp@xQpcpPiXSV*}!yF8{ z2=p&TNzlDO&phoMU2$3yGhbkSCc_{ony-Nr3S@V;07%24T_3v06K@`VO6X?mX0v@? zaWQ-8(>a199nb`0El@;2okkABP0}=MTqcq`&2t&L^IFn9wBDnC#voWP84TLhhY^et znGXDQlu)LneJgvFA~>HwHyzUYGtJC1ZT(DJKNIPb5=D89s9TX-X{z_@Qk|-|VlZ%@ zC=Dvy16oUj7^iYhY$I00^&)N*F^MTMF`OHO^FOm+oX04l!R8r5Q;ONW_ViUjVq9)j3hJ3 zTb}yZAJJdXCNoKRV5e)_q?K=7bhr>n7-s7ISw^8N zX=q3$p&-RDz0lK-QnG~4Ft=Ynas%6PbWc3CsRDf~%9!la7?<{!DfwX$RAd-5s=1+X zVdf(t?!&8BOB$cxngn5r*(W)jrm=)9*Vg*@yZj^r&HyM_PfwA2U_<=2=x84(v zg(n8+Xp5QD$fqBI2Io&`8)S#Yn%`M;CO<)K6dGP6}V* zuB_>Xd}8WseRKy_`v3`2aMl*}aUsC?Sz>efbq06V1+)-Id zi%?uWd7etqr(`at6iuC9%qV%K%vKValjm}CXLD`yr_*0fe^pL@OJq}VP0eWexE9OA z=i}N~CL!IdFd1R|Y$Dz|3K)_NtL^Zh>(MZn+v_@k)e(ksZ21;(ZT)PpF~m3A7AZ~C zEl2EhI|sshDETNE@0#3ha?g_IP`Gf>SFc~sIZZX(u4f9F6vJ$2(;SG7WtwSm2~8#^ zM;sMWmnVFKyd0Ty-llVcR+ZKmW-&%51v_;5^qnOz{sNcS3rxgTUSaxox?p$^8iCaN z9n4||S3>g|nG}T0q@z+>6!R0(GiMN=1^cvNdxFqA9Wvx;? z1$!h@u!RP#n{-FPdW2G$I$8~7F*2JYd$LAT%SgZcO##y*lhaz1|WvFKyWN5aR9 Lk1IY6MkN0O+As4$ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..e4f0529c480d749557f58af1ecd61d2053a98f91 GIT binary patch literal 1529 zcmb7ETTc@~6#iy=+b&d>f`~<>3d%)cOT8u#qC(VaMI*`!PeVJ_f$c8Yoi_T0Fa8jJ zfj((`FoZ{cl<~}VEf^I-}&SmH4ukSwq+{9gmp_<=x#5>;HafP!YT+!f4 zWWX5gE#Bsi%e{v4d~-|GR0au#^rG~nT4G2{O|SPOg|vkvG7L%eR)!42)n0@P3}!>9 zb?&wV!@a5Maqflcwy#|2Ie~cNQY`1`i@@IzfqK6%eF(g!0_in~ZTWvF7H5`vvy4~$ zpy6x@wHa{fg%0;TUvVXUvR8ez+HzfrHSsSLLHMRCbb>pvViPvQ#WcGHob5`o8E zr{Zb-p{#`&>zxQf)mxCW=Q>>dwT# zpOl^n#p_&gO4Dez6Ex~fKeGA(2DVN9cT(?4WYy;xKJ4ulEn~#640~_aGE8lp>a66{ zE?X}nd%I<$#2%#fKc&g@WXw(!j8d{}+NnZvgq2v?veSih-Y^rT%;Wu!#*<0gBt*71 zqMWuZeO@EAkTTQqau1~|9`YKmi@9w@AJ(#8r;p}zReEBz)!Y=pD?M?#2!4&b>pYNp zA3L*avf**n3J5UzvgIk+6cw*6LrIwX2lGv1ef({A0*}C~HNO?qgcikcENE-%jYzYwah^zSMCWpJ=XFA#qV*R2a|Xdqlfj@}1Gs>T zM5cwmjuXmtV$bF;k%FTM^pjAXz)X~Rt{Xqsjh~C-QzR5|nW#HT#-iwhx>N_zI~ok! zCQ5?}cZb$0A;zgr6B|fWaHWE)6-;7^OiWiO@U;!F5Z5ugfxZw{h`A8yP}^h_Lf9eB Khqw@Ji@yQ6XJ1YL literal 0 HcmV?d00001 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 00000000000..693405e9dfd --- /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 00000000000..f5ec705b72a --- /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