Skip to content

Commit

Permalink
Upgrade to Kotlin 1.9.21 (#1077)
Browse files Browse the repository at this point in the history
* WIP - Support Kotlin 1.9.21

* Switch to ZacSweers/kotlin-compile-testing for 1.9.21 support

* Automated fixes

- formatting
- regenerate API

* Handle ClassGeneration extension phase

* Remove unnecessary reference to com.github.tschuchortdev

---------

Co-authored-by: Ben Poland <ben.poland@faire.com>
  • Loading branch information
travisMiehm and bpoland authored Mar 29, 2024
1 parent d372ad2 commit 26abd2d
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 71 deletions.
5 changes: 0 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ plugins {
}

allprojects {
repositories {
mavenCentral()
maven(url = "https://oss.sonatype.org/content/repositories/snapshots/")
}

group = property("projects.group").toString()
}

Expand Down
14 changes: 7 additions & 7 deletions gradle/projects.libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ dokka = "1.8.10"
intellijOpenApi = "7.0.3"
javaAssist = "3.29.2-GA"
junit = "5.9.2"
kotlin = "1.8.21"
kotlinCompileTesting = "1.5.0"
kotlin = "1.9.21"
kotlinCompileTesting = "0.4.0"
javaCompileTesting = "0.21.0"
kotlinBinaryCompatibilityValidator = "0.13.0"
detekt = "1.22.0"
ksp = "1.8.21-1.0.11"
ksp = "1.9.21-1.0.15"

[libraries]
arrowCore = { module = "io.arrow-kt:arrow-core", version.ref = "arrow" }
Expand All @@ -26,17 +26,17 @@ junitEngine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref =
junitPlatformLauncher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit" }
kotlin-annotationProcessingEmbeddable = { module = "org.jetbrains.kotlin:kotlin-annotation-processing-embeddable" }
kotlin-compiler = { module = "org.jetbrains.kotlin:kotlin-compiler" }
kotlin-compilerEmbeddable = { module = "org.jetbrains.kotlin:kotlin-compiler-embeddable" }
kotlin-compilerEmbeddable = { module = "org.jetbrains.kotlin:kotlin-compiler-embeddable", version.ref = "kotlin" }
kotlin-stdlibCommon = { module = "org.jetbrains.kotlin:kotlin-stdlib-common", version.ref = "kotlin" }
kotlin-stdlibJDK8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" }
kotlin-stdlibJS = { module = "org.jetbrains.kotlin:kotlin-stdlib-js" }
kotlin-scriptingCompilerEmbeddable = { module = "org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable" }
kotlin-scriptUtil = { module = "org.jetbrains.kotlin:kotlin-script-util" }
kotlin-scriptUtil = { module = "org.jetbrains.kotlin:kotlin-script-util", version="1.8.22" }
kotlin-gradlePluginX = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin" }
kotlin-gradlePluginApi = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin-api" }
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect" }
kotlinCompileTesting = { module = "com.github.tschuchortdev:kotlin-compile-testing", version.ref = "kotlinCompileTesting" }
kotlinCompileTestingKsp = { module = "com.github.tschuchortdev:kotlin-compile-testing-ksp", version.ref = "kotlinCompileTesting" }
kotlinCompileTesting = { module = "dev.zacsweers.kctfork:core", version.ref = "kotlinCompileTesting" }
kotlinCompileTestingKsp = { module = "dev.zacsweers.kctfork:ksp", version.ref = "kotlinCompileTesting" }
javaCompileTesting = { module = "com.google.testing.compile:compile-testing", version.ref = "javaCompileTesting" }
ksp-api = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" }
ksp-lib = { module = "com.google.devtools.ksp:symbol-processing", version.ref = "ksp" }
Expand Down
85 changes: 46 additions & 39 deletions libs/arrow-meta/api/arrow-meta.api

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import arrow.meta.phases.analysis.CollectAdditionalSources
import arrow.meta.phases.analysis.ExtraImports
import arrow.meta.phases.analysis.PreprocessedVirtualFileFactory
import arrow.meta.phases.codegen.asm.ClassBuilder
import arrow.meta.phases.codegen.asm.ClassGeneration
import arrow.meta.phases.codegen.asm.Codegen
import arrow.meta.phases.codegen.ir.IRGeneration
import arrow.meta.phases.config.Config
Expand All @@ -29,13 +30,14 @@ import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.jvm.extensions.ClassGenerator
import org.jetbrains.kotlin.backend.jvm.extensions.ClassGeneratorExtension
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.codegen.ClassBuilderFactory
import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
import org.jetbrains.kotlin.com.intellij.mock.MockProject
import org.jetbrains.kotlin.com.intellij.openapi.project.Project
Expand Down Expand Up @@ -66,6 +68,7 @@ import org.jetbrains.kotlin.extensions.PreprocessedVirtualFileFactoryExtension
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.TargetPlatform
Expand Down Expand Up @@ -179,6 +182,7 @@ interface InternalRegistry : ConfigSyntax {
is AnalysisHandler -> registerAnalysisHandler(this, ctx)
is ClassBuilder -> registerClassBuilder(this, ctx)
is Codegen -> registerCodegen(this, ctx)
is ClassGeneration -> registerClassGenerator(this, ctx)
is DeclarationAttributeAlterer -> registerDeclarationAttributeAlterer(this, ctx)
is PackageProvider -> packageFragmentProvider(this, ctx)
is SyntheticResolver -> registerSyntheticResolver(this, ctx)
Expand Down Expand Up @@ -605,12 +609,29 @@ interface InternalRegistry : ConfigSyntax {
}
}

fun CompilerPluginRegistrar.ExtensionStorage.registerClassGenerator(
phase: ClassGeneration,
ctx: CompilerContext
) {
ClassGeneratorExtension.registerExtension(
object : ClassGeneratorExtension {
override fun generateClass(
generator: ClassGenerator,
declaration: IrClass?
): ClassGenerator = phase.run { ctx.interceptClassGenerator(generator, declaration) }
}
)
}

fun CompilerPluginRegistrar.ExtensionStorage.registerClassBuilder(
phase: ClassBuilder,
ctx: CompilerContext
) {
ClassBuilderInterceptorExtension.registerExtension(
object : ClassBuilderInterceptorExtension {
@Suppress("DEPRECATION_ERROR")
org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension.registerExtension(
object :
@Suppress("DEPRECATION_ERROR")
org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension {
override fun interceptClassBuilderFactory(
interceptedFactory: ClassBuilderFactory,
bindingContext: BindingContext,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package arrow.meta.phases.codegen.asm

import arrow.meta.phases.CompilerContext
import arrow.meta.phases.ExtensionPhase
import org.jetbrains.kotlin.backend.jvm.extensions.ClassGenerator
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.IrClass

/**
* @see [ExtensionPhase]
* @see [arrow.meta.dsl.codegen.asm.AsmSyntax]
*/
interface ClassGeneration : ExtensionPhase {
@OptIn(ObsoleteDescriptorBasedAPI::class)
fun CompilerContext.interceptClassGenerator(
generator: ClassGenerator,
declaration: IrClass?
): ClassGenerator
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,12 @@ class IrUtils(

fun KotlinType.toIrType(): IrType = typeTranslator.translateType(this)

@OptIn(ObsoleteDescriptorBasedAPI::class)
fun CallableDescriptor.irCall(): IrExpression =
when (this) {
is PropertyDescriptor -> {
val irField = pluginContext.symbols.externalSymbolTable.referenceField(this)
val irField =
pluginContext.symbols.externalSymbolTable.descriptorExtension.referenceField(this)
irField.owner.correspondingPropertySymbol?.owner?.getter?.symbol?.let {
irSimpleFunctionSymbol ->
IrCallImpl(
Expand All @@ -85,7 +87,8 @@ class IrUtils(
?: TODO("Unsupported irCall for $this")
}
is ClassConstructorDescriptor -> {
val irSymbol = pluginContext.symbols.externalSymbolTable.referenceConstructor(this)
val irSymbol =
pluginContext.symbols.externalSymbolTable.descriptorExtension.referenceConstructor(this)
IrConstructorCallImpl(
startOffset = UNDEFINED_OFFSET,
endOffset = UNDEFINED_OFFSET,
Expand All @@ -108,7 +111,10 @@ class IrUtils(
)
}
is FakeCallableDescriptorForObject -> {
val irSymbol = pluginContext.symbols.externalSymbolTable.referenceClass(classDescriptor)
val irSymbol =
pluginContext.symbols.externalSymbolTable.descriptorExtension.referenceClass(
classDescriptor
)
IrGetObjectValueImpl(
startOffset = UNDEFINED_OFFSET,
endOffset = UNDEFINED_OFFSET,
Expand All @@ -121,8 +127,10 @@ class IrUtils(
}
}

@OptIn(ObsoleteDescriptorBasedAPI::class)
fun PropertyDescriptor.irGetterCall(): IrCall? {
val irField = pluginContext.symbols.externalSymbolTable.referenceField(this)
this.backingField
val irField = pluginContext.symbols.externalSymbolTable.descriptorExtension.referenceField(this)
return irField.owner.correspondingPropertySymbol?.owner?.getter?.symbol?.let {
irSimpleFunctionSymbol ->
IrCallImpl(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package arrow.meta.plugin.testing

import com.tschuchort.compiletesting.CompilationResult
import com.tschuchort.compiletesting.KotlinCompilation
import com.tschuchort.compiletesting.KotlinCompilation.Result
import com.tschuchort.compiletesting.PluginOption
import com.tschuchort.compiletesting.SourceFile
import com.tschuchort.compiletesting.kspSourcesDir
Expand All @@ -14,7 +14,8 @@ import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi

internal const val DEFAULT_FILENAME = "Source.kt"

internal fun compile(data: CompilationData): Result {
@OptIn(ExperimentalCompilerApi::class)
internal fun compile(data: CompilationData): CompilationResult {
val compilation = createKotlinCompilation(data)
if (data.symbolProcessors.isEmpty()) {
return compilation.compile()
Expand Down Expand Up @@ -62,6 +63,7 @@ private fun createKotlinCompilation(data: CompilationData) =
pluginOptions = data.pluginOptions.map { PluginOption(it.pluginId, it.key, it.value) }
}

@OptIn(ExperimentalCompilerApi::class)
private val KotlinCompilation.kspGeneratedSourceFiles: List<SourceFile>
get() =
kspSourcesDir
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
@file:OptIn(ExperimentalCompilerApi::class)

package arrow.meta.plugin.testing

import com.tschuchort.compiletesting.CompilationResult
import com.tschuchort.compiletesting.KotlinCompilation.ExitCode
import com.tschuchort.compiletesting.KotlinCompilation.Result
import java.io.File
import java.net.URLClassLoader
import java.nio.file.Files
Expand All @@ -24,8 +22,9 @@ private const val VARIABLE = "[^(]+"
*
* Running the compilation from the provided configuration and getting the results (status, classes,
* and output messages) is possible thanks to
* [Kotlin Compile Testing](https://github.com/tschuchortdev/kotlin-compile-testing), a library
* developed by [Thilo Schuchort](https://github.com/tschuchortdev).
* [Kotlin Compile Testing](https://github.com/ZacSweers/kotlin-compile-testing), a library
* developed by [Thilo Schuchort](https://github.com/tschuchortdev), and forked by
* [ZacSweers](https://github.com/ZacSweers).
*
* Main schema:
* ```
Expand Down Expand Up @@ -61,6 +60,7 @@ private const val VARIABLE = "[^(]+"
*/
fun assertThis(compilerTest: CompilerTest): Unit = compilerTest.run(interpreter)

@OptIn(ExperimentalCompilerApi::class)
private val interpreter: (CompilerTest) -> Unit = {
tailrec fun List<Config>.compilationData(
acc: CompilationData = CompilationData.empty
Expand Down Expand Up @@ -101,7 +101,7 @@ private val interpreter: (CompilerTest) -> Unit = {
)
}

fun runAssert(singleAssert: Assert.SingleAssert, compilationResult: Result): Unit =
fun runAssert(singleAssert: Assert.SingleAssert, compilationResult: CompilationResult): Unit =
when (singleAssert) {
Assert.Empty -> println("Assertions not found")
Assert.CompilationResult.Compiles -> assertCompiles(compilationResult)
Expand All @@ -128,32 +128,40 @@ private val interpreter: (CompilerTest) -> Unit = {
}
}

@OptIn(ExperimentalCompilerApi::class)
private fun CompilationData.addDependencies(config: Config.AddDependencies) =
copy(dependencies = dependencies + config.dependencies.map { it.mavenCoordinates })

@OptIn(ExperimentalCompilerApi::class)
private fun CompilationData.addCompilerPlugins(config: Config.AddCompilerPlugins) =
copy(
compilerPlugins =
compilerPlugins + config.plugins.flatMap { it.dependencies.map { it.mavenCoordinates } }
)

@OptIn(ExperimentalCompilerApi::class)
private fun CompilationData.addMetaPlugins(config: Config.AddMetaPlugins) =
copy(metaPlugins = metaPlugins + config.plugins)

@OptIn(ExperimentalCompilerApi::class)
private fun CompilationData.addArguments(config: Config.AddArguments) =
copy(arguments = arguments + config.arguments)

@OptIn(ExperimentalCompilerApi::class)
private fun CompilationData.addCommandLineProcessors(config: Config.AddCommandLineProcessors) =
copy(commandLineProcessors = commandLineProcessors + config.commandLineProcessors)

@OptIn(ExperimentalCompilerApi::class)
private fun CompilationData.addSymbolProcessors(config: Config.AddSymbolProcessors) =
copy(symbolProcessors = symbolProcessors + config.symbolProcessors)

@OptIn(ExperimentalCompilerApi::class)
private fun CompilationData.addPluginOptions(config: Config.AddPluginOptions) =
copy(pluginOptions = pluginOptions + config.pluginOptions)

@OptIn(ExperimentalCompilerApi::class)
private fun assertEvalsTo(
compilationResult: Result,
compilationResult: CompilationResult,
source: Code.Source,
output: Any?,
onError: (Throwable) -> Any?
Expand All @@ -174,20 +182,24 @@ private fun assertEvalsTo(
}
}

private fun assertCompiles(compilationResult: Result) {
@OptIn(ExperimentalCompilerApi::class)
private fun assertCompiles(compilationResult: CompilationResult) {
assertThat(compilationResult.exitCode).isEqualTo(ExitCode.OK)
}

private fun assertCompilesWith(compilationResult: Result, check: (String) -> Boolean) {
@OptIn(ExperimentalCompilerApi::class)
private fun assertCompilesWith(compilationResult: CompilationResult, check: (String) -> Boolean) {
assertThat(compilationResult.exitCode).isEqualTo(ExitCode.OK)
assertThat(check(compilationResult.messages)).isTrue
}

private fun assertFails(compilationResult: Result) {
@OptIn(ExperimentalCompilerApi::class)
private fun assertFails(compilationResult: CompilationResult) {
assertThat(compilationResult.exitCode).isNotEqualTo(ExitCode.OK)
}

private fun assertFailsWith(compilationResult: Result, check: (String) -> Boolean) {
@OptIn(ExperimentalCompilerApi::class)
private fun assertFailsWith(compilationResult: CompilationResult, check: (String) -> Boolean) {
assertFails(compilationResult)
assertThat(check(compilationResult.messages)).isTrue
}
Expand Down
10 changes: 10 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ dependencyResolutionManagement {
kotlinVersion?.let { version("kotlin", it) }
}
}

repositories {
mavenLocal {
content {
includeGroup("io.arrow-kt")
}
}
mavenCentral()
maven(url = "https://oss.sonatype.org/content/repositories/snapshots/")
}
}

rootProject.name = "arrow-meta-workspace"
Expand Down

0 comments on commit 26abd2d

Please sign in to comment.