Skip to content

Backport kxDT-as-KUP infrastructure and migration changes #560

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions benchmarks/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask

/*
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the import below the copyright header so that it stays a header.

* Copyright 2019-2023 JetBrains s.r.o. and contributors.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
Expand Down Expand Up @@ -32,3 +34,10 @@ tasks.named<Jar>("jmhJar") {
repositories {
mavenCentral()
}

// !! infrastructure for builds as a Kotlin user project
tasks.named("assemble") {
// compile all Kotlin code from the module during full-repository builds
// so that it's covered during builds as a Kotlin user project
dependsOn(tasks.withType<KotlinCompilationTask<*>>())
}
103 changes: 85 additions & 18 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile

plugins {
id("kotlinx.team.infra") version "0.4.0-dev-85"
kotlin("multiplatform") apply false
Expand All @@ -20,30 +26,46 @@ infra {
val mainJavaToolchainVersion by ext(project.property("java.mainToolchainVersion"))
val modularJavaToolchainVersion by ext(project.property("java.modularToolchainVersion"))

// !! infrastructure for builds as a Kotlin user project
val shouldWarningsBeErrors = providers.gradleProperty("kotlin_Werror_override")
.map { optionalWErrorOverride ->
when (optionalWErrorOverride) {
"enable" -> true
"disable" -> false
else -> error("Unknown value for 'kotlin_Werror_override': $optionalWErrorOverride")
}
}
.getOrElse(false)
.also { logger.info("shouldWarningsBeErrors: $it") }

allprojects {
repositories {
addTrainRepositories(project)
mavenCentral()
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
// outputs the compiler version to logs so we can check whether the train configuration applied
kotlinOptions.freeCompilerArgs += "-version"
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile>().configureEach {
compilerOptions { freeCompilerArgs.add("-Xjvm-default=all-compatibility") }
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile>().configureEach {
compilerOptions { freeCompilerArgs.add("-Xpartial-linkage-loglevel=ERROR") }
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile>().configureEach {
compilerOptions { freeCompilerArgs.add("-Xpartial-linkage-loglevel=ERROR") }

// !! infrastructure for builds as a Kotlin user project
val optionalKotlinArtifactsRepo = providers.gradleProperty("kotlin_repo_url").orNull
if (optionalKotlinArtifactsRepo != null) {
maven(url = optionalKotlinArtifactsRepo)
logger.info(
"[ktDT-as-KUP] Registered '$optionalKotlinArtifactsRepo' as a dependency Maven repository for '${path}'"
)
}
}
}

// Disable NPM to NodeJS nightly compatibility check.
// Drop this when NodeJs version that supports latest Wasm become stable
tasks.withType<org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinNpmInstallTask>().configureEach {
args.add("--ignore-engines")
subprojects {
tasks.withType<KotlinCompilationTask<*>>().configureEach {
compilerOptions {
allWarningsAsErrors.set(shouldWarningsBeErrors)
}
}

// drop this after migration to 2.2.0
tasks.withType<KotlinJvmCompile>().configureEach {
compilerOptions {
freeCompilerArgs.add("-Xjvm-default=all-compatibility")
}
}
}

kover {
Expand All @@ -61,3 +83,48 @@ dependencies {
kover(project(":kotlinx-datetime"))
kover(project(":kotlinx-datetime-serialization"))
}

// !! infrastructure for builds as a Kotlin user project
subprojects {
tasks.withType<KotlinCompilationTask<*>>().configureEach {
compilerOptions {
// output reported warnings even in the presence of reported errors
freeCompilerArgs.add("-Xreport-all-warnings")
// output kotlin.git-searchable names of reported diagnostics
freeCompilerArgs.add("-Xrender-internal-diagnostic-names")

with(providers) {
gradleProperty("kotlin_language_version").orNull?.let { optionalOverridingKotlinLV ->
languageVersion.set(KotlinVersion.fromVersion(optionalOverridingKotlinLV))
logger.info(
"[ktDT-as-KUP] Overrode the Kotlin language version with $optionalOverridingKotlinLV for '$path'"
)
}
gradleProperty("kotlin_api_version").orNull?.let { optionalOverridingKotlinAPIV ->
apiVersion.set(KotlinVersion.fromVersion(optionalOverridingKotlinAPIV))
logger.info(
"[ktDT-as-KUP] Overrode the Kotlin API version with $optionalOverridingKotlinAPIV for '$path'"
)
}
gradleProperty("kotlin_additional_cli_options").orNull?.let { optionalAdditionalCLIOptions ->
if (optionalAdditionalCLIOptions.isNotBlank()) {
freeCompilerArgs.addAll(optionalAdditionalCLIOptions.split(" "))
logger.info(
"[ktDT-as-KUP] Added the following Kotlin CLI options to '$path': $optionalAdditionalCLIOptions"
)
}
}
}
}
}
tasks.withType<KotlinNativeCompile>().configureEach {
compilerOptions {
freeCompilerArgs.add("-Xpartial-linkage-loglevel=error")
}
}
tasks.withType<Kotlin2JsCompile>().configureEach {
compilerOptions {
freeCompilerArgs.add("-Xpartial-linkage-loglevel=error")
}
}
}
47 changes: 26 additions & 21 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,38 @@ plugins {
`kotlin-dsl`
}

val props = Properties().apply {
file("../gradle.properties").inputStream().use { load(it) }
}
repositories {
mavenCentral()
gradlePluginPortal()

// copy-pasted from `CommunityProjectsBuild`, see the explanation there
fun RepositoryHandler.addTrainRepositories(project: Project) {
if (project.rootProject.properties["build_snapshot_train"]?.toString()?.toBoolean() == true) {
mavenLocal()
// !! infrastructure for builds as a Kotlin user project
val optionalKotlinArtifactsRepo = providers.gradleProperty("kotlin_repo_url").orNull
if (optionalKotlinArtifactsRepo != null) {
maven(url = optionalKotlinArtifactsRepo)
logger.info(
"[ktDT-as-KUP] Registered '$optionalKotlinArtifactsRepo' as a dependency Maven repository for buildSrc"
)
}
(project.rootProject.properties["kotlin_repo_url"] as? String)?.let(::maven)
}

// copy-pasted from `CommunityProjectsBuild`, but uses `props` to obtain the non-snapshot version, because
// we don't have access to the properties defined in `gradle.properties` of the encompassing project
val Project.kotlinVersion: String
get() = if (rootProject.properties["build_snapshot_train"]?.toString()?.toBoolean() == true) {
rootProject.properties["kotlin_snapshot_version"] as? String ?: error("kotlin_snapshot_version must be specified")
} else {
props.getProperty("defaultKotlinVersion")
// !! infrastructure for builds as a Kotlin user project
val Project.kotlinVersion: String by lazy {
val optionalOverridingKotlinVersion = providers.gradleProperty("kotlin_version").orNull
if (optionalOverridingKotlinVersion != null) {
logger.info(
"[ktDT-as-KUP] Overrode the Kotlin distribution version with $optionalOverridingKotlinVersion"
)
optionalOverridingKotlinVersion
} else {
// we don't have access to the properties defined in `gradle.properties` of the encompassing project,
// so we have to get them manually
val properties = Properties().apply {
file("../gradle.properties").inputStream().use { load(it) }
}
properties.getProperty("defaultKotlinVersion")
}
}

repositories {
mavenCentral()
gradlePluginPortal()
addTrainRepositories(project)
}

dependencies {
fun gradlePlugin(id: String, version: String): String = "$id:$id.gradle.plugin:$version"
implementation(gradlePlugin("org.jetbrains.kotlin.multiplatform", kotlinVersion))
Expand Down
50 changes: 0 additions & 50 deletions buildSrc/src/main/kotlin/CommunityProjectsBuild.kt

This file was deleted.

29 changes: 6 additions & 23 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import javax.xml.parsers.DocumentBuilderFactory
import java.io.ByteArrayOutputStream
import java.io.PrintWriter
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.JsModuleKind
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.konan.target.Family

Expand Down Expand Up @@ -102,16 +103,13 @@ kotlin {
}
}
compilations.all {
kotlinOptions {
sourceMap = true
moduleKind = "umd"
compileTaskProvider.configure {
compilerOptions {
sourceMap = true
moduleKind = JsModuleKind.MODULE_UMD
}
}
}
// compilations["main"].apply {
// kotlinOptions {
// outputFile = "kotlinx-datetime-tmp.js"
// }
// }
}

wasmJs {
Expand Down Expand Up @@ -412,21 +410,6 @@ dokka {
}
}

// Disable intermediate sourceSet compilation because we do not need js-wasmJs artifact
tasks.configureEach {
if (name == "compileCommonJsMainKotlinMetadata") {
enabled = false
}
}

// Drop this configuration when the Node.JS version in KGP will support wasm gc milestone 4
// check it here:
// https://github.com/JetBrains/kotlin/blob/master/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/nodejs/NodeJsRootExtension.kt
with(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.apply(rootProject)) {
nodeVersion = "21.0.0-v8-canary202309167e82ab1fa2"
nodeDownloadBaseUrl = "https://nodejs.org/download/v8-canary"
}

apiValidation {
@OptIn(kotlinx.validation.ExperimentalBCVApi::class)
klib {
Expand Down
9 changes: 1 addition & 8 deletions core/common/src/DateTimeUnit.kt
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,7 @@ public sealed class DateTimeUnit {
* @see DateTimeUnit.MonthBased for specifically month-based units.
*/
@Serializable(with = DateBasedDateTimeUnitSerializer::class)
public sealed class DateBased : DateTimeUnit() {
@Suppress("TOPLEVEL_TYPEALIASES_ONLY")
@Deprecated("Use DateTimeUnit.DayBased", ReplaceWith("DateTimeUnit.DayBased", "kotlinx.datetime.DateTimeUnit"))
public typealias DayBased = DateTimeUnit.DayBased
@Suppress("TOPLEVEL_TYPEALIASES_ONLY")
@Deprecated("Use DateTimeUnit.MonthBased", ReplaceWith("DateTimeUnit.MonthBased", "kotlinx.datetime.DateTimeUnit"))
public typealias MonthBased = DateTimeUnit.MonthBased
}
public sealed class DateBased : DateTimeUnit()

/**
* A [datetime unit][DateTimeUnit] equal to some number of calendar days.
Expand Down
1 change: 1 addition & 0 deletions core/common/test/ClockTimeSourceTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package kotlinx.datetime.test

import kotlinx.datetime.*
import kotlinx.datetime.asClock
import kotlin.test.*
import kotlin.time.*
import kotlin.time.Duration.Companion.days
Expand Down
7 changes: 4 additions & 3 deletions core/commonKotlin/src/internal/Tzfile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ internal fun readTzFile(data: ByteArray): TzFile {
override fun toString(): String = "Ttinfo(utoff=$utoff, isdst=$isdst, abbrind=$abbrind)"
}

fun abbreviationForIndex(abbreviations: List<Byte>, startIndex: UByte): String = abbreviations.drop(startIndex.toInt())
.takeWhile { byte -> byte != 0.toByte() }.toByteArray().decodeToString()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commit message says that this change was introduced because of https://youtrack.jetbrains.com/issue/KT-77986/, but I don't see the connection. This is just a function, not a local class. Could you please elaborate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIU, the KT-77986 fix addressed a more general problem of the compiler not running relevant checks in nested local scopes (regardless of whether the subject is a class or a function), and this function was previously located in a local function inside a local function.

I see that we have a slightly more applicable ticket (created precisely as a result of this kxDT-as-KUP hit), though: https://youtrack.jetbrains.com/issue/KT-78976/, – so I can link it instead.


inline fun BinaryDataReader.readData(header: Header, readTime: () -> Long): TzFileData {
val transitionTimes = List(header.timecnt) { readTime() }
val transitionTypes = List(header.timecnt) { readByte() }
Expand All @@ -99,8 +102,6 @@ internal fun readTzFile(data: ByteArray): TzFile {
)
}
val abbreviations = List(header.charcnt) { readByte() }
fun abbreviationForIndex(startIndex: UByte): String = abbreviations.drop(startIndex.toInt())
.takeWhile { byte -> byte != 0.toByte() }.toByteArray().decodeToString()
val leapSecondRules = List(header.leapcnt) {
TzFileData.LeapSecondRule(
readTime(),
Expand All @@ -114,7 +115,7 @@ internal fun readTzFile(data: ByteArray): TzFile {
return TzFileData(
leapSecondRules,
transitionTimes.zip(transitionTypes) { time, type -> TzFileData.Transition(time, type.toInt()) },
ttinfos.map { TzFileData.ClockState(TzFileOffset(it.utoff), it.isdst, abbreviationForIndex(it.abbrind)) }
ttinfos.map { TzFileData.ClockState(TzFileOffset(it.utoff), it.isdst, abbreviationForIndex(abbreviations, it.abbrind)) }
)
}

Expand Down
4 changes: 1 addition & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ bcvVersion=0.17.0
java.mainToolchainVersion=8
java.modularToolchainVersion=11

kotlin.js.compiler=ir
kotlin.native.ignoreIncorrectDependencies=true
kotlin.native.ignoreDisabledTargets=true
kotlin.mpp.applyDefaultHierarchyTemplate=false
kotlin.native.ignoreDisabledTargets=true

org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
org.jetbrains.dokka.experimental.gradle.pluginMode.nowarn=true
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 3 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=ff7bf6a86f09b9b2c40bb8f48b25fc19cf2b2664fd1d220cd7ab833ec758d0d7
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
distributionSha256Sum=9d926787066a081739e8200858338b4a69e837c3a821a33aca9db09dd4a41026
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@FenstonSingel FenstonSingel Jul 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIR, this line was added automatically by ./gradlew wrapper --gradle-version 8.5.
I decided that it knew better than me. 😅

zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading