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

Migrate to Kotlin 2.1 #627

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
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
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id("org.openrewrite.build.recipe-library") version "latest.release"
kotlin("jvm") version "1.9.25"
kotlin("jvm") version "2.1.10"
}
group = "org.openrewrite"
description = "Rewrite Kotlin"
Expand All @@ -13,7 +13,7 @@ val latest = if (project.hasProperty("releasing")) {
"latest.integration"
}

val kotlinVersion = "1.9.25"
val kotlinVersion = "2.1.10"

dependencies {
annotationProcessor("org.projectlombok:lombok:latest.release")
Expand Down
96 changes: 96 additions & 0 deletions src/main/java/org/openrewrite/kotlin/FirSessionFactoryHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite.kotlin

import org.jetbrains.kotlin.cli.jvm.compiler.VfsBasedProjectEnvironment
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.session.FirJvmSessionFactory
import org.jetbrains.kotlin.fir.session.FirSessionConfigurator
import org.jetbrains.kotlin.fir.session.IncrementalCompilationContext
import org.jetbrains.kotlin.fir.session.createSymbolProviders
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.ImportTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.TargetPlatform

object FirSessionFactoryHelper {

fun createSessionWithDependencies(
moduleName: Name,
platform: TargetPlatform,
externalSessionProvider: FirProjectSessionProvider?,
projectEnvironment: VfsBasedProjectEnvironment,
languageVersionSettings: LanguageVersionSettings,
javaSourcesScope: AbstractProjectFileSearchScope,
lookupTracker: LookupTracker?,
enumWhenTracker: EnumWhenTracker?,
importTracker: ImportTracker?,
incrementalCompilationContext: IncrementalCompilationContext?,
extensionRegistrars: List<FirExtensionRegistrar>,
needRegisterJavaElementFinder: Boolean,
dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {},
sessionConfigurator: FirSessionConfigurator.() -> Unit = {},
): FirSession {
val librariesScope: AbstractProjectFileSearchScope = !javaSourcesScope
val binaryModuleData = BinaryModuleData.initialize(moduleName, platform)
val dependencyList = DependencyListForCliModule.build(binaryModuleData, init = dependenciesConfigurator)
val sessionProvider = externalSessionProvider ?: FirProjectSessionProvider()
val packagePartProvider = projectEnvironment.getPackagePartProvider(librariesScope)
val librarySession = FirJvmSessionFactory.createLibrarySession(
moduleName,
sessionProvider,
dependencyList.moduleDataProvider,
projectEnvironment,
extensionRegistrars,
librariesScope,
packagePartProvider,
languageVersionSettings,
predefinedJavaComponents = null,
)

val mainModuleData = FirModuleDataImpl(
moduleName,
dependencyList.regularDependencies,
dependencyList.dependsOnDependencies,
dependencyList.friendsDependencies,
platform,
)
return FirJvmSessionFactory.createModuleBasedSession(
mainModuleData,
sessionProvider,
javaSourcesScope,
projectEnvironment,
{ incrementalCompilationContext?.createSymbolProviders(it, mainModuleData, projectEnvironment) },
extensionRegistrars,
languageVersionSettings,
JvmTarget.DEFAULT,
lookupTracker,
enumWhenTracker,
importTracker,
predefinedJavaComponents = null,
needRegisterJavaElementFinder,
init = {
// registerComponent(FirBuiltinSyntheticFunctionInterfaceProvider::class, librarySession.symbolProvider)
sessionConfigurator()
},
)
}
}
19 changes: 13 additions & 6 deletions src/main/java/org/openrewrite/kotlin/KotlinParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
import org.jetbrains.kotlin.fir.pipeline.FirUtilsKt;
import org.jetbrains.kotlin.fir.resolve.ScopeSession;
import org.jetbrains.kotlin.fir.session.FirSessionConfigurator;
import org.jetbrains.kotlin.fir.session.FirSessionFactoryHelper;
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope;
import org.jetbrains.kotlin.idea.KotlinFileType;
import org.jetbrains.kotlin.idea.KotlinLanguage;
Expand Down Expand Up @@ -263,7 +262,7 @@ public static class Builder extends Parser.Builder {
private boolean logCompilationWarningsAndErrors;
private final List<NamedStyles> styles = new ArrayList<>();
private String moduleName = "main";
private KotlinLanguageLevel languageLevel = KotlinLanguageLevel.KOTLIN_1_9;
private KotlinLanguageLevel languageLevel = KotlinLanguageLevel.KOTLIN_2_1;
private boolean isKotlinScript = false;

public Builder() {
Expand Down Expand Up @@ -431,7 +430,7 @@ public CompiledSource parse(List<Parser.Input> sources, Disposable disposable, E
VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL),
providerFunction1);

AbstractProjectFileSearchScope sourceScope = projectEnvironment.getSearchScopeByPsiFiles(ktFiles, false);
AbstractProjectFileSearchScope sourceScope = projectEnvironment.getSearchScopeByPsiFiles(ktFiles);
sourceScope.plus(projectEnvironment.getSearchScopeForProjectJavaSources());

AbstractProjectFileSearchScope libraryScope = projectEnvironment.getSearchScopeForProjectLibraries();
Expand Down Expand Up @@ -461,12 +460,10 @@ public CompiledSource parse(List<Parser.Input> sources, Disposable disposable, E
FirSession firSession = FirSessionFactoryHelper.INSTANCE.createSessionWithDependencies(
Name.identifier(module.getModuleName()),
JvmPlatforms.INSTANCE.getUnspecifiedJvmPlatform(),
JvmPlatformAnalyzerServices.INSTANCE,
sessionProvider,
projectEnvironment,
languageVersionSettings,
sourceScope,
libraryScope,
compilerConfiguration.get(LOOKUP_TRACKER),
compilerConfiguration.get(ENUM_WHEN_TRACKER),
compilerConfiguration.get(IMPORT_TRACKER),
Expand Down Expand Up @@ -525,7 +522,9 @@ public enum KotlinLanguageLevel {
KOTLIN_1_6,
KOTLIN_1_7,
KOTLIN_1_8,
KOTLIN_1_9
KOTLIN_1_9,
KOTLIN_2_0,
KOTLIN_2_1
}

private CompilerConfiguration compilerConfiguration() {
Expand Down Expand Up @@ -571,6 +570,10 @@ private LanguageVersion getLanguageVersion(KotlinLanguageLevel languageLevel) {
return LanguageVersion.KOTLIN_1_8;
case KOTLIN_1_9:
return LanguageVersion.KOTLIN_1_9;
case KOTLIN_2_0:
return LanguageVersion.KOTLIN_2_0;
case KOTLIN_2_1:
return LanguageVersion.KOTLIN_2_1;
default:
throw new IllegalArgumentException("Unknown language level: " + languageLevel);
}
Expand Down Expand Up @@ -598,6 +601,10 @@ private ApiVersion getApiVersion(KotlinLanguageLevel languageLevel) {
return ApiVersion.KOTLIN_1_8;
case KOTLIN_1_9:
return ApiVersion.KOTLIN_1_9;
case KOTLIN_2_0:
return ApiVersion.KOTLIN_2_0;
case KOTLIN_2_1:
return ApiVersion.KOTLIN_2_1;
default:
throw new IllegalArgumentException("Unknown language level: " + languageLevel);
}
Expand Down
33 changes: 16 additions & 17 deletions src/main/java/org/openrewrite/kotlin/internal/PsiTreePrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import org.jetbrains.kotlin.fir.declarations.FirProperty;
import org.jetbrains.kotlin.fir.expressions.*;
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference;
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag;
import org.jetbrains.kotlin.fir.types.*;
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor;
import org.jetbrains.kotlin.ir.IrElement;
Expand Down Expand Up @@ -135,11 +134,11 @@ public static class TreePrinterContext {
@Override
public @Nullable Void visitElement(FirElement firElement, TreePrinterContext ctx) {
StringBuilder line = new StringBuilder();
line.append(leftPadding(ctx.getDepth()))
line.append(leftPadding(ctx.depth))
.append(printFirElement(firElement));
connectToLatestSibling(ctx.getDepth(), ctx.getLines());
ctx.getLines().add(line);
ctx.setDepth(ctx.getDepth() + 1);
connectToLatestSibling(ctx.depth, ctx.lines);
ctx.lines.add(line);
ctx.depth++;
firElement.acceptChildren(this, ctx);

if (firElement instanceof FirResolvedTypeRef) {
Expand All @@ -150,7 +149,7 @@ public static class TreePrinterContext {
}
}

ctx.setDepth(ctx.getDepth() - 1);
ctx.depth--;
return null;
}
}.visitFile(file, context);
Expand All @@ -167,11 +166,11 @@ public static class TreePrinterContext {
@Override
public @Nullable Void visitElement(FirElement fir, TreePrinterContext ctx) {
StringBuilder line = new StringBuilder();
line.append(leftPadding(ctx.getDepth()))
line.append(leftPadding(ctx.depth))
.append(printFirElement(fir));
connectToLatestSibling(ctx.getDepth(), ctx.getLines());
ctx.getLines().add(line);
ctx.setDepth(ctx.getDepth() + 1);
connectToLatestSibling(ctx.depth, ctx.lines);
ctx.lines.add(line);
ctx.depth++;
fir.acceptChildren(this, ctx);

if (fir instanceof FirResolvedTypeRef) {
Expand All @@ -182,7 +181,7 @@ public static class TreePrinterContext {
}
}

ctx.setDepth(ctx.getDepth() - 1);
ctx.depth--;
return null;
}
}.visitElement(firElement, context);
Expand All @@ -193,10 +192,10 @@ public static class TreePrinterContext {
public static class IrPrinter {
public void printElement(IrElement element, PsiTreePrinter.TreePrinterContext ctx) {
StringBuilder line = new StringBuilder();
line.append(leftPadding(ctx.getDepth()))
line.append(leftPadding(ctx.depth))
.append(printIrElement(element));
connectToLatestSibling(ctx.getDepth(), ctx.getLines());
ctx.getLines().add(line);
connectToLatestSibling(ctx.depth, ctx.lines);
ctx.lines.add(line);
}
}

Expand Down Expand Up @@ -545,7 +544,7 @@ private static String printConeKotlinType(ConeTypeProjection coneKotlinType) {
return ((FirProperty) firElement).getName().toString();
} else if (firElement instanceof FirResolvedTypeRef) {
FirResolvedTypeRef resolvedTypeRef = (FirResolvedTypeRef) firElement;
ConeKotlinType coneKotlinType = resolvedTypeRef.getType();
ConeKotlinType coneKotlinType = resolvedTypeRef.getConeType();
return printConeKotlinType(coneKotlinType);
} else if (firElement instanceof FirResolvedNamedReference) {
return ((FirResolvedNamedReference) firElement).getName().toString();
Expand Down Expand Up @@ -575,8 +574,8 @@ private static String printConeKotlinType(ConeTypeProjection coneKotlinType) {
}
return sb.toString();
}
} else if (firElement instanceof FirConstExpression) {
Object value = ((FirConstExpression<?>) firElement).getValue();
} else if (firElement instanceof FirLiteralExpression) {
Object value = ((FirLiteralExpression) firElement).getValue();
return value != null ? value.toString() : null;
// return ((FirConstExpression<?>) firElement).getKind().toString();
} else if (firElement instanceof FirWhenBranch) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/org/openrewrite/kotlin/KotlinIrTypeMapping.kt
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class KotlinIrTypeMapping(typeCache: JavaTypeCache) : JavaTypeMapping<Any> {
return type(baseType.type)
}

is IrConst<*> -> {
is IrConst -> {
return primitive(baseType)
}

Expand Down Expand Up @@ -516,7 +516,7 @@ class KotlinIrTypeMapping(typeCache: JavaTypeCache) : JavaTypeMapping<Any> {

fun primitive(type: Any?): JavaType.Primitive {
return when (type) {
is IrConst<*> -> {
is IrConst -> {
when (type.kind) {
IrConstKind.Int -> JavaType.Primitive.Int
IrConstKind.Boolean -> JavaType.Primitive.Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class KotlinTypeIrSignatureBuilder : JavaTypeSignatureBuilder {
return signature(baseType.type)
}

is IrConst<*> -> {
is IrConst -> {
return primitiveSignature(baseType)
}

Expand Down Expand Up @@ -265,7 +265,7 @@ class KotlinTypeIrSignatureBuilder : JavaTypeSignatureBuilder {

override fun primitiveSignature(type: Any): String {
return when (type) {
is IrConst<*> -> type.type.classFqName!!.asString()
is IrConst -> type.type.classFqName!!.asString()
else -> {
throw UnsupportedOperationException("Unsupported primitive type" + type.javaClass)
}
Expand Down
Loading