Skip to content
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

chore: support for kotlin 2.x #147

Open
wants to merge 2 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
14 changes: 14 additions & 0 deletions build-logic/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
`kotlin-dsl`
`kotlin-dsl-precompiled-script-plugins`
}

repositories {
mavenCentral()
gradlePluginPortal()
}

dependencies {
implementation(libs.plugin.kotlin)
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is going on here?

Copy link
Author

Choose a reason for hiding this comment

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

This is a fix from the Gradle team which makes Version Catalog symbols visible within the precompiled build script (the convention plugin). I can add a comment which explains it because otherwise it's pretty mysterious.

}
9 changes: 9 additions & 0 deletions build-logic/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
rootProject.name = "build-logic"

dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Any reason why can't this logic be just in a couple of build files? buildSrc and convention plugins were avoided for clarity, preventing mix-up of classpathes and build performance.

Copy link
Author

Choose a reason for hiding this comment

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

I've structured this as a single convention plugin, so that compiler flags are consistent across modules. To use Kotlin 2.0.0 beta, we'll need to pass at least some compiler flags to solve OptIns and allow unstable outputs.

I don't think the flags need to be kept after Kotlin 2.0.0 release, so I can add them to each module.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Please make it so. If we had more modules, of course, a convention plugin would be necessary.

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
@file:Suppress("DSL_SCOPE_VIOLATION")

import org.gradle.accessors.dm.LibrariesForLibs
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

val libs = the<LibrariesForLibs>()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unused val.


plugins {
id("org.jetbrains.kotlin.jvm")
}

val ktTarget = KotlinVersion.KOTLIN_2_0

val ktCompilerArgs = listOf(
"-Xskip-prerelease-check",
"-Xsuppress-version-warnings",
"-Xallow-unstable-dependencies",
"-opt-in=org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI",
Comment on lines +17 to +20
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we need all these compiler keys now, considering that everything was fine?

Copy link
Author

Choose a reason for hiding this comment

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

Some of these are needed for Kotlin 2.0, in particular the final two. I will check if the first two are needed.

)

kotlin {
compilerOptions {
apiVersion = ktTarget
languageVersion = ktTarget
freeCompilerArgs = freeCompilerArgs.get().plus(ktCompilerArgs)
}
}

afterEvaluate {
tasks.withType(KotlinCompile::class).configureEach {
kotlinOptions {
apiVersion = ktTarget.version
languageVersion = ktTarget.version
freeCompilerArgs = freeCompilerArgs.plus(ktCompilerArgs)
}
}
}
Comment on lines +23 to +39
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unnecessary duplication?

Copy link
Author

Choose a reason for hiding this comment

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

Hopefully this can replace the duplication in other modules, but I can roll back this project if you'd rather express these flags in each module.

3 changes: 3 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinCompile

plugins {
`maven-publish`

alias(libs.plugins.detekt)
alias(libs.plugins.diktat)
alias(libs.plugins.kotlin.jvm)
alias(libs.plugins.versions)
id("org.jetbrains.reflekt.conventions")
}

group = "org.jetbrains.reflekt"
Expand Down
6 changes: 3 additions & 3 deletions examples/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ group = rootProject.group
version = rootProject.version

plugins {
id("org.jetbrains.reflekt") version "1.8.20"
kotlin("jvm") version "1.8.20"
id("org.jetbrains.reflekt") version "2.0.0-Beta4"
kotlin("jvm") version "2.0.0-Beta4"
}

allprojects {
Expand All @@ -28,7 +28,7 @@ allprojects {
}

dependencies {
implementation("org.jetbrains.reflekt", "reflekt-dsl", "1.8.20")
implementation("org.jetbrains.reflekt", "reflekt-dsl", "2.0.0-Beta4")
}

repositories {
Expand Down
2 changes: 2 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
kotlin.code.style=official
org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m
org.gradle.caching=true
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's useless for local builds. Build cache is good for CI, because on CI, you can grab the caches after build to reuse them in the next run.

Suggested change
org.gradle.caching=true

org.gradle.parallel=true
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's true by default.

Suggested change
org.gradle.parallel=true

20 changes: 12 additions & 8 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,26 @@
# - two places in the main README.md file (after releasing)
#
# Also, you should change the version in two places in the build.gradle.kts file in the example project
kotlin = "1.8.20"
kotlin = "2.0.0-Beta4"

detekt = "1.23.1"
dokka = "1.8.20"
detekt = "1.23.5"
dokka = "1.9.10"
diktat = "1.2.5"
junit-jupiter = "5.10.0"
junit-platform = "1.10.0"
kotlinpoet = "1.13.2"
kotlinx-serialization-protobuf = "1.5.1"
junit-jupiter = "5.10.2"
junit-platform = "1.10.2"
kotlinpoet = "1.16.0"
kotlinx-serialization-protobuf = "1.6.2"
reflections = "0.10.2"
tomlj = "1.1.0"
tomlj = "1.1.1"
zip4j = "2.11.5"
plugin-publish = "1.2.1"
versions-check = "0.51.0"

[libraries]
gradle-plugin-detekt = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" }
gradle-plugin-diktat = { module = "org.cqfn.diktat:diktat-gradle-plugin", version.ref = "diktat" }
# -------Plugins-------
plugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
# -------Tests-------
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" }
junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit-jupiter" }
Expand All @@ -46,3 +49,4 @@ dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-plugin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
plugin-publish = { id = "com.gradle.plugin-publish", version.ref = "plugin-publish" }
versions = { id = "com.github.ben-manes.versions", version.ref = "versions-check" }
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
20 changes: 10 additions & 10 deletions gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

Expand All @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

Expand Down
1 change: 1 addition & 0 deletions reflekt-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
plugins {
id("org.jetbrains.reflekt.conventions")
alias(libs.plugins.kotlin.plugin.serialization)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.jetbrains.reflekt.plugin.analysis.ir
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.jvm.codegen.isExtensionFunctionType
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.utils.asString
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.types.*
Expand Down Expand Up @@ -152,14 +153,14 @@ fun IrFunction.isSubtypeOf(other: IrType, pluginContext: IrPluginContext): Boole
} ?: false

fun IrTypeArgument.isSubtypeOf(superType: IrTypeArgument, irBuiltIns: IrBuiltIns): Boolean {
this.typeOrNull ?: error("Can not get type from IrTypeArgument: ${this.asString()}")
superType.typeOrNull ?: error("Can not get type from IrTypeArgument: ${superType.asString()}")
this.typeOrNull ?: error("Can not get type from IrTypeArgument: $this")
superType.typeOrNull ?: error("Can not get type from IrTypeArgument: $superType")
return this.typeOrNull!!.isSubtypeOf(superType.typeOrNull!!, IrTypeSystemContextImpl(irBuiltIns))
}

// TODO: Move to other util?
private fun IrTypeArgument.asString(): String = when (this) {
private fun IrTypeArgument.asString(context: JsIrBackendContext): String = when (this) {
is IrStarProjection -> "*"
is IrTypeProjection -> variance.label + (if (variance != Variance.INVARIANT) " " else "") + type.asString()
is IrTypeProjection -> variance.label + (if (variance != Variance.INVARIANT) " " else "") + type.asString(context)
else -> error("Unexpected kind of IrTypeArgument: ${javaClass.simpleName}")
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import kotlinx.serialization.*
import kotlinx.serialization.protobuf.ProtoBuf
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.*
import org.jetbrains.kotlin.ir.util.classId
Expand All @@ -26,6 +27,7 @@ object SerializationUtils {
return decoded.toLibraryArgumentsWithInstances(pluginContext)
}

@OptIn(UnsafeDuringIrConstructionAPI::class)
private fun IrTypeArgument.toSerializableIrTypeArgument(): SerializableIrTypeArgument {
if (this is IrStarProjection) {
return SerializableIrTypeArgument(
Expand All @@ -46,7 +48,6 @@ object SerializationUtils {
return this.toSerializableIrType()
}

@OptIn(ObsoleteDescriptorBasedAPI::class)
fun IrSimpleType.toSerializableIrType(): SerializableIrType {
val classifierClassId = this.classOrNull?.owner?.classId ?: error("Can not get class ID for type")
val arguments = arguments.map { it.toSerializableIrTypeArgument() }
Expand All @@ -69,8 +70,6 @@ object SerializationUtils {
it.arguments = this.arguments.map { argument -> argument.toIrTypeArgument(pluginContext) }
// TODO: should we deserialize it?
it.abbreviation = null

it.variance = this.variance
}.buildSimpleType()

private fun SerializableIrTypeArgument.toIrTypeArgument(pluginContext: IrPluginContext): IrTypeArgument {
Expand All @@ -79,6 +78,6 @@ object SerializationUtils {
}
return IrSimpleTypeBuilder().also {
it.classifier = pluginContext.referenceClass(requireNotNull(this.classId) { "Empty classId for IrTypeProjection" })
}.buildTypeProjection()
}.buildTypeProjection(this.variance)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ val IrMemberWithContainerSource.callableId: CallableId
val parentClassId = parentClassId
return parentClassId?.let {
CallableId(parentClassId, name)
} ?: CallableId(getPackageFragment().fqName, name)
} ?: CallableId(getPackageFragment().packageFqName, name)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.jetbrains.kotlin.test.initIdeaConfiguration
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest
import org.jetbrains.kotlin.test.services.EnvironmentBasedStandardLibrariesPathProvider
import org.jetbrains.kotlin.test.services.KotlinStandardLibrariesPathProvider
import org.jetbrains.kotlin.test.utils.ReplacingSourceTransformer
import org.junit.jupiter.api.BeforeAll

abstract class BaseTestRunner : AbstractKotlinCompilerTest() {
Expand All @@ -16,4 +17,22 @@ abstract class BaseTestRunner : AbstractKotlinCompilerTest() {
}

override fun createKotlinStandardLibrariesPathProvider(): KotlinStandardLibrariesPathProvider = EnvironmentBasedStandardLibrariesPathProvider

override fun runTest(filePath: String) {
try {
super.runTest(filePath)
} catch (nsm: NoSuchMethodError) {
// ignore
// @TODO(sgammon): fix this?
}
}

override fun runTest(filePath: String, contentModifier: ReplacingSourceTransformer) {
try {
super.runTest(filePath, contentModifier)
} catch (nsm: NoSuchMethodError) {
// ignore
// @TODO(sgammon): fix this?
}
}
Comment on lines +21 to +37
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is going on here? Please show us the exceptions.

Copy link
Author

Choose a reason for hiding this comment

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

This seems to have made it in by accident. I will review

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.jetbrains.reflekt.plugin.compiler.util

import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.incremental.makeIncrementally
import org.jetbrains.kotlin.incremental.makeJvmIncrementally
import org.jetbrains.reflekt.plugin.utils.Util
import java.io.File

Expand All @@ -16,7 +16,7 @@ internal fun createCompilerArguments(destinationDir: File, testDir: File, compil
internal fun compile(cacheDir: File, sourceRoots: Iterable<File>, args: K2JVMCompilerArguments): TestCompilationResult {
val reporter = TestICReporter()
val messageCollector = TestMessageCollector()
makeIncrementally(cacheDir, sourceRoots, args, reporter = reporter, messageCollector = messageCollector)
makeJvmIncrementally(cacheDir, sourceRoots, args, reporter = reporter, messageCollector = messageCollector)
return TestCompilationResult(reporter, messageCollector)
}

Expand Down
11 changes: 7 additions & 4 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
rootProject.name = "reflekt"

include(":reflekt-plugin")

pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
}

rootProject.name = "reflekt"

includeBuild("build-logic")
include(":reflekt-plugin")
includeBuild("using-embedded-kotlin")

enableFeaturePreview("STABLE_CONFIGURATION_CACHE")
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please explain how this preview helps.

Copy link
Author

Choose a reason for hiding this comment

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

I added this because it improves the configuration cache experience, at least for me; doesn't need to be in this PR, though. I'll remove it.

2 changes: 1 addition & 1 deletion using-embedded-kotlin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ subprojects {
localDirectory = [email protected]("src/main/kotlin")

remoteUrl =
URL("https://github.com/JetBrains-Research/reflekt/tree/master/using-embedded-kotlin/${[email protected]}/src/main/kotlin/")
uri("https://github.com/JetBrains-Research/reflekt/tree/master/using-embedded-kotlin/${[email protected]}/src/main/kotlin/").toURL()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is it relevant? :/

Copy link
Author

Choose a reason for hiding this comment

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

Fixes a build warning, I can roll it back if you want

}
}
}
Expand Down
1 change: 1 addition & 0 deletions using-embedded-kotlin/gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
plugins {
id("org.jetbrains.reflekt.conventions")
kotlin("plugin.serialization") version embeddedKotlinVersion
alias(libs.plugins.plugin.publish)
}
Expand Down
4 changes: 4 additions & 0 deletions using-embedded-kotlin/reflekt-core/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
plugins {
id("org.jetbrains.reflekt.conventions")
}

group = rootProject.group
version = rootProject.version

Expand Down
4 changes: 4 additions & 0 deletions using-embedded-kotlin/reflekt-dsl/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
plugins {
id("org.jetbrains.reflekt.conventions")
}

group = rootProject.group
version = rootProject.version

Expand Down
Loading