Skip to content

Commit 95b6feb

Browse files
Add support for Kotlin 2.2
1 parent 845ad86 commit 95b6feb

7 files changed

Lines changed: 266 additions & 10 deletions

File tree

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ allprojects {
88

99
subprojects {
1010
repositories {
11+
mavenLocal()
1112
mavenCentral()
1213
maven { url 'https://jitpack.io' }
1314
google()
14-
mavenLocal()
1515
}
1616
}
1717

kmp-library/build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ plugins {
44
id 'java-test-fixtures'
55
id 'maven-publish'
66
id "org.jlleitschuh.gradle.ktlint" version '10.2.1'
7-
id "org.jetbrains.kotlin.jvm" version "2.1.0"
7+
id "org.jetbrains.kotlin.jvm" version "2.2.0"
88
id 'signing'
99
}
1010

@@ -26,9 +26,9 @@ test {
2626
dependencies {
2727
api('com.guardsquare:proguard-core:9.1.8')
2828

29-
testImplementation "org.jetbrains.kotlin:kotlin-stdlib:2.1.0"
30-
testImplementation "org.jetbrains.kotlin:kotlin-reflect:2.1.0"
31-
testImplementation group: "dev.zacsweers.kctfork", name: "core", version: "0.5.0"
29+
testImplementation "org.jetbrains.kotlin:kotlin-stdlib:2.2.0"
30+
testImplementation "org.jetbrains.kotlin:kotlin-reflect:2.2.0"
31+
testImplementation group: "dev.zacsweers.kctfork", name: "core", version: "0.8.0"
3232
testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.7.2' // for kotest framework
3333
testImplementation 'io.kotest:kotest-runner-junit5-jvm:5.7.2' // for kotest framework
3434
testImplementation 'io.kotest:kotest-assertions-core-jvm:5.7.2' // for kotest core jvm assertions

kmp-library/src/test/kotlin/AnnotationClassTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class AnnotationClassTest : FunSpec({
2828

2929
testKtMetadata.trimEnd() shouldBe """
3030
/**
31-
* Kotlin class (metadata version 2.1.0).
31+
* Kotlin class (metadata version 2.2.0).
3232
* From Java class: MyAnnotation
3333
*/
3434
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)

kmp-library/src/test/kotlin/ContextReceiverTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class ContextReceiverTest : FunSpec({
3939
val testKtMetadata = programClassPool.getClass("TestKt").processingInfo as String
4040
testKtMetadata.trimEnd() shouldBe """
4141
/**
42-
* Kotlin file facade (metadata version 2.1.0).
42+
* Kotlin file facade (metadata version 2.2.0).
4343
* From Java class: TestKt
4444
*/
4545
@@ -52,7 +52,7 @@ class ContextReceiverTest : FunSpec({
5252

5353
fooMetadata.trimEnd() shouldBe """
5454
/**
55-
* Kotlin class (metadata version 2.1.0).
55+
* Kotlin class (metadata version 2.2.0).
5656
* From Java class: Foo
5757
*/
5858
context(LoggerContext, FooBar)

kmp-library/src/test/kotlin/FlagTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class FlagTest : FunSpec({
2929

3030
testKtMetadata.trimEnd() shouldBe """
3131
/**
32-
* Kotlin file facade (metadata version 2.1.0).
32+
* Kotlin file facade (metadata version 2.2.0).
3333
* From Java class: TestKt
3434
*/
3535
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
import com.guardsquare.proguard.kotlin.printer.KotlinMetadataPrinter
2+
import io.kotest.core.spec.style.FunSpec
3+
import io.kotest.matchers.shouldBe
4+
import proguard.classfile.kotlin.visitor.ReferencedKotlinMetadataVisitor
5+
import proguard.testutils.ClassPoolBuilder
6+
import proguard.testutils.KotlinSource
7+
8+
class KotlinTwoPointTwoTest : FunSpec({
9+
test("Non-local break & continue") {
10+
val (programClassPool, _) = ClassPoolBuilder.fromSource(
11+
KotlinSource(
12+
"Test.kt",
13+
"""
14+
fun processList(elements: List<Int>): Boolean {
15+
for (element in elements) {
16+
val variable = element ?: run {
17+
continue
18+
}
19+
if (variable == 0) return true
20+
}
21+
return false
22+
}
23+
""".trimIndent(),
24+
)
25+
)
26+
27+
programClassPool.classesAccept(
28+
ReferencedKotlinMetadataVisitor(
29+
KotlinMetadataPrinter(
30+
programClassPool
31+
)
32+
)
33+
)
34+
35+
val testKtMetadata = programClassPool.getClass("TestKt").processingInfo as String
36+
println(testKtMetadata)
37+
38+
testKtMetadata.trimEnd() shouldBe """
39+
/**
40+
* Kotlin file facade (metadata version 2.2.0).
41+
* From Java class: TestKt
42+
*/
43+
44+
// Functions
45+
46+
fun processList(elements: List<Int>): Boolean { }
47+
""".trimIndent()
48+
}
49+
test("Nested type aliases") {
50+
val (programClassPool, _) = ClassPoolBuilder.fromSource(
51+
KotlinSource(
52+
"Test.kt",
53+
"""
54+
class Container {
55+
typealias ContainerSet = Set<Container>
56+
}
57+
58+
""".trimIndent(),
59+
),
60+
kotlincArguments = listOf("-Xnested-type-aliases")
61+
)
62+
63+
programClassPool.classesAccept(
64+
ReferencedKotlinMetadataVisitor(
65+
KotlinMetadataPrinter(
66+
programClassPool
67+
)
68+
)
69+
)
70+
71+
val containerMetadata = programClassPool.getClass("Container").processingInfo as String
72+
println(containerMetadata)
73+
74+
containerMetadata.trimEnd() shouldBe """
75+
/**
76+
* Kotlin class (metadata version 2.2.0).
77+
* From Java class: Container
78+
*/
79+
class Container {
80+
81+
// Type aliases
82+
83+
typealias ContainerSet = Set<Container>
84+
}
85+
""".trimIndent()
86+
}
87+
test("RequiresOptIn annotations") {
88+
val (programClassPool, _) = ClassPoolBuilder.fromSource(
89+
KotlinSource(
90+
"Test.kt",
91+
"""
92+
@RequiresOptIn(
93+
level = RequiresOptIn.Level.WARNING,
94+
message = "Interfaces in this library are experimental"
95+
)
96+
annotation class UnstableApi()
97+
98+
@SubclassOptInRequired(UnstableApi::class)
99+
interface CoreLibraryApi
100+
""".trimIndent(),
101+
),
102+
)
103+
104+
programClassPool.classesAccept(
105+
ReferencedKotlinMetadataVisitor(
106+
KotlinMetadataPrinter(
107+
programClassPool
108+
)
109+
)
110+
)
111+
val coreLibraryApiMetadata = programClassPool.getClass("CoreLibraryApi").processingInfo as String
112+
println(coreLibraryApiMetadata)
113+
114+
coreLibraryApiMetadata.trimEnd() shouldBe """
115+
/**
116+
* Kotlin class (metadata version 2.2.0).
117+
* From Java class: CoreLibraryApi
118+
*/
119+
@SubclassOptInRequired(markerClass = {UnstableApi})
120+
interface CoreLibraryApi
121+
""".trimIndent()
122+
123+
val unstableApiMetadata = programClassPool.getClass("UnstableApi").processingInfo as String
124+
println(unstableApiMetadata)
125+
126+
unstableApiMetadata.trimEnd() shouldBe """
127+
/**
128+
* Kotlin class (metadata version 2.2.0).
129+
* From Java class: UnstableApi
130+
*/
131+
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
132+
@RequiresOptIn(message = "Interfaces in this library are experimental", level = RequiresOptIn.Level.WARNING)
133+
annotation class UnstableApi
134+
""".trimIndent()
135+
}
136+
test("Guard conditions in when with a subject") {
137+
val (programClassPool, _) = ClassPoolBuilder.fromSource(
138+
KotlinSource(
139+
"Test.kt",
140+
"""
141+
sealed interface Animal {
142+
data class Cat(val mouseHunter: Boolean) : Animal {
143+
fun feedCat() {}
144+
}
145+
146+
data class Dog(val breed: String) : Animal {
147+
fun feedDog() {}
148+
}
149+
}
150+
151+
fun feedAnimal(animal: Animal) {
152+
when (animal) {
153+
is Animal.Dog -> animal.feedDog()
154+
is Animal.Cat if !animal.mouseHunter -> animal.feedCat()
155+
else -> println("Unknown animal")
156+
}
157+
}
158+
""".trimIndent(),
159+
)
160+
)
161+
162+
programClassPool.classesAccept(
163+
ReferencedKotlinMetadataVisitor(
164+
KotlinMetadataPrinter(
165+
programClassPool
166+
)
167+
)
168+
)
169+
170+
val testKtMetadata = programClassPool.getClass("TestKt").processingInfo as String
171+
println(testKtMetadata)
172+
173+
testKtMetadata.trimEnd() shouldBe """
174+
/**
175+
* Kotlin file facade (metadata version 2.2.0).
176+
* From Java class: TestKt
177+
*/
178+
179+
// Functions
180+
181+
fun feedAnimal(animal: Animal) { }
182+
""".trimIndent()
183+
}
184+
test("Multi-dollar string interpolation") {
185+
val (programClassPool, _) = ClassPoolBuilder.fromSource(
186+
KotlinSource(
187+
"Test.kt",
188+
"""
189+
class MultiDollar {
190+
companion object {
191+
val multiDollarString: String
192+
get() = ${"$$"}${"\"\"\""}aMultiDollarString${"\"\"\""}
193+
}
194+
}
195+
""".trimIndent(),
196+
)
197+
)
198+
199+
programClassPool.classesAccept(
200+
ReferencedKotlinMetadataVisitor(
201+
KotlinMetadataPrinter(
202+
programClassPool
203+
)
204+
)
205+
)
206+
207+
val multiDollarMetadata = programClassPool.getClass("MultiDollar").processingInfo as String
208+
println(multiDollarMetadata)
209+
210+
multiDollarMetadata.trimEnd() shouldBe """
211+
/**
212+
* Kotlin class (metadata version 2.2.0).
213+
* From Java class: MultiDollar
214+
*/
215+
class MultiDollar {
216+
217+
// Kotlin companion class from Java class: MultiDollar${"$"}Companion
218+
companion object {
219+
220+
// Properties
221+
222+
val multiDollarString: String
223+
get // getter method: public final java.lang.String getMultiDollarString()
224+
}
225+
226+
// Synthetic inner classes - these were generated by the Kotlin compiler from e.g. lambdas
227+
228+
// Kotlin companion class from Java class: MultiDollar${"$"}Companion
229+
companion object {
230+
231+
// Properties
232+
233+
val multiDollarString: String
234+
get // getter method: public final java.lang.String getMultiDollarString()
235+
}
236+
}
237+
""".trimIndent()
238+
239+
val multiDollarCompanionMetadata = programClassPool.getClass("MultiDollar${"$"}Companion").processingInfo as String
240+
println(multiDollarCompanionMetadata)
241+
242+
multiDollarCompanionMetadata.trimEnd() shouldBe """
243+
/**
244+
* Kotlin companion class (metadata version 2.2.0).
245+
* From Java class: MultiDollar${"$"}Companion
246+
*/
247+
companion object MultiDollar_Companion {
248+
249+
// Properties
250+
251+
val multiDollarString: String
252+
get // getter method: public final java.lang.String getMultiDollarString()
253+
}
254+
""".trimIndent()
255+
}
256+
})

kmp-library/src/test/kotlin/PrimitiveInAnnotationTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class PrimitiveInAnnotationTest : FunSpec({
3737

3838
testKtMetadata.trimEnd() shouldBe """
3939
/**
40-
* Kotlin class (metadata version 2.1.0).
40+
* Kotlin class (metadata version 2.2.0).
4141
* From Java class: Test
4242
*/
4343
@Serializer(forClass = Int::class)

0 commit comments

Comments
 (0)