Skip to content

Conversation

@Crustack
Copy link
Contributor

@Crustack Crustack commented Nov 25, 2025

What's changed?

  • Update kotlin-compiler dependencies to 2.2.21
  • Implement JvmFirPipeline to use current K2 phased compiler API (with disabled fail on compile errors) to generate FirFiles
  • Update KotlinIrTypeMapping, IrTreeVisitor, KotlinTypeIrSignatureBuilder to be compilable, but they are not used atm
  • Update KotlinTypeMapping, KotlinTypeSignatureBuilder, PsiElementAssociations for new compiler dependency versions to be compilable
  • Check all rewrite-kotlin and rewrite-gradle tests still work and adjust KotlinTypeMapping, KotlinTypeSignatureBuilder, PsiElementAssociations if necessary
  • For synthetic source files the contents are pasted into a temp folder to provide compiler with actual file path

What's your motivation?

Anyone you would like to review specifically?

@shanman190
@jkschneider

Checklist

  • I've added unit tests to cover both positive and negative cases
  • I've read and applied the recipe conventions and best practices
  • I've used the IntelliJ IDEA auto-formatter on affected files

@Crustack Crustack marked this pull request as ready for review December 13, 2025 12:06
@Crustack
Copy link
Contributor Author

Crustack commented Dec 13, 2025

@timtebeek @shanman190 @jkschneider PR is now ready for proper review

FYI: I also tested adding support for properly compiling build.gradle.kts with Kotlin DSL, which works great and enables proper Kotlin support for many gradle recipes.
I will add another PR for it if/after this has been merged

Copy link
Member

@timtebeek timtebeek left a comment

Choose a reason for hiding this comment

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

Thanks for your continued efforts here @Crustack ! For the uninitiated (me) could you explain a bit about the what the FIR processing is / adds, and any trade offs as compared to what we had before, and impact on say Kotlin v1 support? That would mean we're better able to review this work, as it seems promising but it's a bit hard to say without more context.

Comment on lines +351 to +377
// TODO: Compiler Source File args need to be an actual file path therefore copying synthetic file to temp folder
public static String tempFile(ExecutionContext ctx, Input source, AtomicInteger idx) {
String fileName;
if ("openRewriteFile.kt".equals(source.getPath().toString())) {
fileName = "openRewriteFile" + idx.getAndIncrement() + ".kt";
} else if ("openRewriteFile.kts".equals(source.getPath().toString())) {
fileName = "openRewriteFile" + idx.getAndIncrement() + ".kts";
} else {
fileName = source.getPath().toString();
}
if(TEMP_SOURCE_DIR == null) {
try {
TEMP_SOURCE_DIR = Files.createTempDirectory("rewrite");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
addJvmClasspathRoot(compilerConfiguration, PathUtil.getResourcePathForClass(AnnotationTarget.class));
Path tempFile = TEMP_SOURCE_DIR.resolve(fileName);
try {
Files.createDirectories(tempFile.getParent());
Files.copy(source.getSource(ctx), tempFile, StandardCopyOption.REPLACE_EXISTING);
} catch (FileAlreadyExistsException ignored) {
} catch (IOException e) {
throw new RuntimeException(e);
}
return tempFile.toAbsolutePath().toString();
}
Copy link
Member

Choose a reason for hiding this comment

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

Calling this out for my colleagues as creating files on disk might be a little different when it concerns the CLI / workers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was trying to use the WorkingDirectoryExecutionContextView's working directory to create these temp files (which is only necessary for synthetic temp files in Unit Tests), but executing:

WorkingDirectoryExecutionContextView.view(ctx).getWorkingDirectory()

In Unit Tests throws NullPointerException, because the context has no CURRENT_CYCLE` message. Not sure how to proceed on this.

Comment on lines +574 to +587
is IrSimpleType -> {
when (type.getPrimitiveType()) {
PrimitiveType.INT -> JavaType.Primitive.Int
PrimitiveType.BOOLEAN -> JavaType.Primitive.Boolean
PrimitiveType.BYTE -> JavaType.Primitive.Byte
PrimitiveType.CHAR -> JavaType.Primitive.Char
PrimitiveType.DOUBLE -> JavaType.Primitive.Double
PrimitiveType.FLOAT -> JavaType.Primitive.Float
PrimitiveType.LONG -> JavaType.Primitive.Long
PrimitiveType.SHORT -> JavaType.Primitive.Short
else -> when {
type.isStringClassType() -> JavaType.Primitive.String
type.isNothing() || type.isNullableNothing() -> JavaType.Primitive.None
else -> JavaType.Primitive.None
Copy link
Member

Choose a reason for hiding this comment

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

Love that you've thought to do this as well; it's been a bit of a sore point to me that some Spring migration method patterns failed to match because they were using Java primitives instead of Kotlin primitives.

@timtebeek
Copy link
Member

Thanks for your continued efforts here @Crustack ! For the uninitiated (me) could you explain a bit about the what the FIR processing is / adds, and any trade offs as compared to what we had before, and impact on say Kotlin v1 support? That would mean we're better able to review this work, as it seems promising but it's a bit hard to say without more context.

Not sure if you'd seen my earlier comment @Crustack , but it would help us better judge the scope & impact of the work done here, and how it compares to our support for Kotlin v1. Is v1 still supported with your changes for instance?

@Crustack
Copy link
Contributor Author

Crustack commented Jan 18, 2026

Not sure if you'd seen my earlier comment @Crustack , but it would help us better judge the scope & impact of the work done here, and how it compares to our support for Kotlin v1. Is v1 still supported with your changes for instance?

Hi @timtebeek , sorry for not responding earlier.
With the changes of this PR:

  • KotlinParser still uses PSI+FIR as before, but just with the newer Kotlin Compiler API
  • Uses the new K2 Compiler and supports Kotlin v2 (which was already attempted by Kotlin 2 #5963, Add support for Kotlin 2.x #5575)
  • All Kotlin Tests also pass for e.g. Kotlin v1.9
  • I also figured out how to utilize gradle Kotlin Script Templates with the new compiler API to better parse build.gradle.kts files and improve method/field matching for them (which I can submit in a future PR)
  • In a next step you could improve Kotlin parsing further by compiling to IR by adding the JvmFir2IrPipelinePhase to JvmFirPipeline (see JvmCliPipeline)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

Support for Kotlin 2.2.0 Projects

2 participants