Update Kotlin to 2.0 (#900)

- update Kotlin from 1.7.10 to 2.0.21
  - Kotlin 1.6 dependencies in Gradle lock files are expected because kotlinc,
    which is also used by some tests, internally uses some 1.6 dependencies
    for backwards compatibility reasons.
- update kotlinx-html and kotlinx-serialization
- adapt Kotlin code where necessary
- use Kotlin stdlib Path APIs where possible
- fix IntelliJ Kotlin inspection warnings
- reformat code with `./gradlew spotlessApply`
  - ktfmt adds lots of trailing commas
- Add workaround to fix IntelliJ "unresolved reference" errors
This commit is contained in:
odenix
2025-01-23 14:41:59 -08:00
committed by GitHub
parent cdd6d52642
commit 258eda8630
87 changed files with 1042 additions and 1004 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,9 @@
package org.pkl.codegen.kotlin
import java.io.IOException
import kotlin.io.path.createParentDirectories
import org.pkl.commons.cli.CliCommand
import org.pkl.commons.cli.CliException
import org.pkl.commons.createParentDirectories
import org.pkl.commons.writeString
import org.pkl.core.Closeables
import org.pkl.core.ModuleSource

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package org.pkl.codegen.kotlin
import com.squareup.kotlinpoet.*
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import java.io.StringWriter
import java.net.URI
import java.util.*
import org.pkl.commons.NameMapper
import org.pkl.core.*
@@ -76,7 +75,7 @@ class KotlinCodeGenerator(
private val PMODULE = PModule::class.asClassName()
private val PCLASS = PClass::class.asClassName()
private val REGEX = Regex::class.asClassName()
private val URI = URI::class.asClassName()
private val URI = java.net.URI::class.asClassName()
private val VERSION = Version::class.asClassName()
private const val PROPERTY_PREFIX: String = "org.pkl.config.java.mapper."
@@ -134,7 +133,7 @@ class KotlinCodeGenerator(
fun generateCompanionRelatedCode(
builder: TypeSpec.Builder,
isModuleType: Boolean = false
isModuleType: Boolean = false,
): TypeSpec.Builder {
// ensure that at most one companion object is generated for this type
val companionObjectBuilder: Lazy<TypeSpec.Builder> = lazy {
@@ -153,7 +152,7 @@ class KotlinCodeGenerator(
"serialVersionUID",
Long::class.java,
KModifier.PRIVATE,
KModifier.CONST
KModifier.CONST,
)
.initializer("0L")
.build()
@@ -307,7 +306,7 @@ class KotlinCodeGenerator(
builder.addStatement(
"if (this.$accessor != other.$accessor) return false",
propertyName,
propertyName
propertyName,
)
}
@@ -329,7 +328,7 @@ class KotlinCodeGenerator(
builder.addStatement(
"result = 31 * result + %T.hashCode($accessor)",
Objects::class,
propertyName
propertyName,
)
}
@@ -355,14 +354,14 @@ class KotlinCodeGenerator(
}
add(")")
}
.build()
.build(),
)
.build()
}
fun generateDeprecation(
annotations: Collection<PObject>,
addAnnotation: (AnnotationSpec) -> Unit
addAnnotation: (AnnotationSpec) -> Unit,
) {
annotations
.firstOrNull { it.classInfo == PClassInfo.Deprecated }
@@ -511,7 +510,7 @@ class KotlinCodeGenerator(
private fun generateEnumTypeSpec(
typeAlias: TypeAlias,
stringLiterals: Set<String>
stringLiterals: Set<String>,
): TypeSpec.Builder {
val enumConstantToPklNames =
stringLiterals
@@ -545,7 +544,7 @@ class KotlinCodeGenerator(
for ((enumConstantName, pklName) in enumConstantToPklNames) {
builder.addEnumConstant(
enumConstantName,
TypeSpec.anonymousClassBuilder().addSuperclassConstructorParameter("%S", pklName).build()
TypeSpec.anonymousClassBuilder().addSuperclassConstructorParameter("%S", pklName).build(),
)
}
@@ -636,7 +635,7 @@ class KotlinCodeGenerator(
PClassInfo.Pair ->
KOTLIN_PAIR.parameterizedBy(
if (typeArguments.isEmpty()) ANY_NULL else typeArguments[0].toKotlinPoetName(),
if (typeArguments.isEmpty()) ANY_NULL else typeArguments[1].toKotlinPoetName()
if (typeArguments.isEmpty()) ANY_NULL else typeArguments[1].toKotlinPoetName(),
)
PClassInfo.Collection ->
COLLECTION.parameterizedBy(
@@ -655,7 +654,7 @@ class KotlinCodeGenerator(
PClassInfo.Mapping ->
MAP.parameterizedBy(
if (typeArguments.isEmpty()) ANY_NULL else typeArguments[0].toKotlinPoetName(),
if (typeArguments.isEmpty()) ANY_NULL else typeArguments[1].toKotlinPoetName()
if (typeArguments.isEmpty()) ANY_NULL else typeArguments[1].toKotlinPoetName(),
)
PClassInfo.Module -> PMODULE
PClassInfo.Class -> PCLASS

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,17 +20,11 @@ import javax.script.ScriptException
import kotlin.reflect.KClass
import kotlin.text.RegexOption.MULTILINE
import kotlin.text.RegexOption.UNIX_LINES
import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback
class CompilationFailedException(msg: String?, cause: Throwable? = null) :
RuntimeException(msg, cause)
object InMemoryKotlinCompiler {
init {
// prevent "Unable to load JNA library" warning
setIdeaIoUseFallback()
}
// Implementation notes:
// * all [sourceFiles] are currently combined into a single file
// * implementation makes assumptions about structure of generated source files
@@ -43,14 +37,16 @@ object InMemoryKotlinCompiler {
"^(data |open |enum )?class\\s+(\\w+) *(\\([^)]*\\))?.*$\\n((^ .*\\n|^$\\n)*)",
transform: (String, String) -> Sequence<Pair<String, String>> = { name, body ->
sequenceOf(Pair(name, prefix + name)) + body.findClasses("$prefix$name.")
}
},
): Sequence<Pair<String, String>> = // (simpleName1, qualifiedName1), ...
Regex(regex, setOf(MULTILINE, UNIX_LINES)).findAll(this).flatMap {
transform(it.groupValues[nameGroup], it.groupValues[bodyGroup].trimIndent())
}
fun String.findOuterObjects(): Sequence<Pair<String, String>> = // (simpleName, qualifiedName)
findClasses("", 1, 2, "^object\\s+(\\w+).*$\n((^ .*$\n|^$\n)*)") { name, body ->
findClasses(nameGroup = 1, bodyGroup = 2, regex = "^object\\s+(\\w+).*$\n((^ .*$\n|^$\n)*)") {
name,
body ->
body.findClasses("$name.")
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import org.junit.jupiter.api.assertAll
import org.junit.jupiter.api.assertDoesNotThrow
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.io.TempDir
import org.pkl.commons.test.ReflectionUtils.enumValues
import org.pkl.core.*
import org.pkl.core.util.IoUtils
@@ -67,7 +68,7 @@ class KotlinCodeGeneratorTest {
"do",
"when",
"interface",
"typeof"
"typeof",
)
private val simpleClass: KClass<*> by lazy {
@@ -139,7 +140,7 @@ class KotlinCodeGeneratorTest {
pklCode: String,
generateKdoc: Boolean = false,
generateSpringBootConfig: Boolean = false,
implementSerializable: Boolean = false
implementSerializable: Boolean = false,
): KotlinSourceCode {
val module = Evaluator.preconfigured().evaluateSchema(ModuleSource.text(pklCode))
@@ -150,8 +151,8 @@ class KotlinCodeGeneratorTest {
KotlinCodeGeneratorOptions(
generateKdoc = generateKdoc,
generateSpringBootConfig = generateSpringBootConfig,
implementSerializable = implementSerializable
)
implementSerializable = implementSerializable,
),
)
return KotlinSourceCode(generator.kotlinFile)
}
@@ -435,7 +436,7 @@ class KotlinCodeGeneratorTest {
"digit-1" to "DIGIT_1",
"42" to "_42",
"àœü" to "ÀŒÜ",
"日本-つくば" to "日本_つくば"
"日本-つくば" to "日本_つくば",
)
val kotlinCode =
generateKotlinCode(
@@ -445,27 +446,16 @@ class KotlinCodeGeneratorTest {
"""
.trimIndent()
)
val kotlinClass = kotlinCode.compile().getValue("MyTypeAlias").java
val kotlinClass = kotlinCode.compile().getValue("MyTypeAlias")
assertThat(kotlinClass.enumConstants.size)
assertThat(kotlinClass.enumValues().size)
.isEqualTo(cases.size) // make sure zip doesn't drop cases
assertAll(
"generated enum constants have correct names",
kotlinClass.declaredFields.zip(cases) { field, (_, kotlinName) ->
kotlinClass.enumValues().zip(cases) { enumValue, (pklName, kotlinName) ->
{
assertThat(field.name).isEqualTo(kotlinName)
Unit
}
}
)
assertAll(
"toString() returns Pkl name",
kotlinClass.enumConstants.zip(cases) { enumConstant, (pklName, _) ->
{
assertThat(enumConstant.toString()).isEqualTo(pklName)
Unit
assertThat(enumValue.name).isEqualTo(kotlinName)
assertThat(enumValue.toString()).isEqualTo(pklName)
}
}
)
@@ -1048,7 +1038,7 @@ class KotlinCodeGeneratorTest {
typealias Email = String(contains("@"))
"""
.trimIndent(),
generateKdoc = true
generateKdoc = true,
)
assertThat(kotlinCode).compilesSuccessfully().isEqualToResourceFile("Kdoc.kotlin")
@@ -1066,7 +1056,7 @@ class KotlinCodeGeneratorTest {
class Product
"""
.trimIndent(),
generateKdoc = true
generateKdoc = true,
)
assertThat(kotlinCode)
@@ -1428,7 +1418,7 @@ class KotlinCodeGeneratorTest {
}
"""
.trimIndent(),
generateSpringBootConfig = true
generateSpringBootConfig = true,
)
assertThat(kotlinCode)
@@ -1470,7 +1460,7 @@ class KotlinCodeGeneratorTest {
pigeon: Person
"""
.trimIndent()
.trimIndent(),
)
val client =
@@ -1485,7 +1475,7 @@ class KotlinCodeGeneratorTest {
parrot: library.Person
"""
.trimIndent()
.trimIndent(),
)
val kotlinSourceFiles = generateFiles(library, client)
@@ -1520,7 +1510,7 @@ class KotlinCodeGeneratorTest {
pigeon: Person
"""
.trimIndent()
.trimIndent(),
)
val derived =
@@ -1535,7 +1525,7 @@ class KotlinCodeGeneratorTest {
person1: Person
person2: Person2
"""
.trimIndent()
.trimIndent(),
)
val kotlinSourceFiles = generateFiles(base, derived)
@@ -1584,7 +1574,7 @@ class KotlinCodeGeneratorTest {
typealias Version = "LATEST"|String
"""
.trimIndent()
.trimIndent(),
)
val moduleTwo =
@@ -1597,7 +1587,7 @@ class KotlinCodeGeneratorTest {
v: Version = "1.2.3"
"""
.trimIndent()
.trimIndent(),
)
val kotlinSourceFiles = generateFiles(moduleOne, moduleTwo)
@@ -1638,7 +1628,7 @@ class KotlinCodeGeneratorTest {
prop: Int
}
"""
.trimIndent()
.trimIndent(),
)
val generated = generateFiles(pklModule)
val expectedPropertyFile =
@@ -1692,7 +1682,7 @@ class KotlinCodeGeneratorTest {
abstract class NotSerializable
"""
.trimIndent(),
implementSerializable = true
implementSerializable = true,
)
assertThat(kotlinCode)
@@ -1731,7 +1721,7 @@ class KotlinCodeGeneratorTest {
smallStruct,
Regex("(i?)\\w*"),
smallStruct,
enumValue
enumValue,
)
fun confirmSerDe(instance: Any) {
@@ -1777,7 +1767,7 @@ class KotlinCodeGeneratorTest {
street: String
}
""",
implementSerializable = true
implementSerializable = true,
)
assertThat(kotlinCode)
@@ -1814,7 +1804,7 @@ class KotlinCodeGeneratorTest {
someProp: String
"""
.trimIndent()
.trimIndent(),
)
)
assertThat(kotlinCode).containsKey("kotlin/Foo(2a)Bar.kt")
@@ -1840,7 +1830,7 @@ class KotlinCodeGeneratorTest {
bar: Int = 123
"""
.trimIndent()
.trimIndent(),
)
.toMutableMap()
@@ -1882,7 +1872,7 @@ class KotlinCodeGeneratorTest {
baz: String
"""
.trimIndent()
.trimIndent(),
)
.toMutableMap()
@@ -1897,7 +1887,7 @@ class KotlinCodeGeneratorTest {
// ---
"kotlin/w/org/baz/Module3.kt" to listOf("package w.org.baz", "data class Module3("),
"$MAPPER_PREFIX/org.baz.Module3.properties" to
listOf("org.pkl.config.java.mapper.org.baz.Module3\\#ModuleClass=w.org.baz.Module3")
listOf("org.pkl.config.java.mapper.org.baz.Module3\\#ModuleClass=w.org.baz.Module3"),
)
}
@@ -1909,7 +1899,7 @@ class KotlinCodeGeneratorTest {
mapOf(
"org.foo" to "com.foo.x",
"org.bar.Module2" to "org.bar.RenamedModule",
"org.baz" to "com.baz.a.b"
"org.baz" to "com.baz.a.b",
)
)
.generateFiles(
@@ -1944,7 +1934,7 @@ class KotlinCodeGeneratorTest {
owner: Module2.Group
}
"""
.trimIndent()
.trimIndent(),
)
files.validateContents(
@@ -1961,7 +1951,7 @@ class KotlinCodeGeneratorTest {
"package org.bar",
"import com.foo.x.Module1",
"object RenamedModule {",
"val owner: Module1.Person"
"val owner: Module1.Person",
),
"$MAPPER_PREFIX/org.bar.Module2.properties" to
listOf(
@@ -1974,7 +1964,7 @@ class KotlinCodeGeneratorTest {
"package com.baz.a.b",
"import org.bar.RenamedModule",
"object Module3 {",
"val owner: RenamedModule.Group"
"val owner: RenamedModule.Group",
),
"$MAPPER_PREFIX/org.baz.Module3.properties" to
listOf(
@@ -2004,7 +1994,7 @@ class KotlinCodeGeneratorTest {
bar: Int = 123
"""
.trimIndent()
.trimIndent(),
)
files.validateContents(
@@ -2087,7 +2077,7 @@ class KotlinCodeGeneratorTest {
Regex("(i?)\\w*"),
other,
other,
enumValue
enumValue,
)
return other to propertyTypes
@@ -2099,7 +2089,7 @@ class KotlinCodeGeneratorTest {
private class KotlinSourceCodeAssert(actual: KotlinSourceCode) :
AbstractAssert<KotlinSourceCodeAssert, KotlinSourceCode>(
actual,
KotlinSourceCodeAssert::class.java
KotlinSourceCodeAssert::class.java,
) {
fun contains(expected: String): KotlinSourceCodeAssert {
if (!actual.text.contains(expected)) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
package org.pkl.codegen.kotlin
import java.nio.file.Path
import org.pkl.commons.createParentDirectories
import kotlin.io.path.createParentDirectories
import org.pkl.commons.writeString
data class PklModule(val name: String, val content: String) {

View File

@@ -1 +0,0 @@
org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory