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

Support Kotlin-based templates #218

Closed
knutwannheden opened this issue Aug 14, 2023 · 4 comments
Closed

Support Kotlin-based templates #218

knutwannheden opened this issue Aug 14, 2023 · 4 comments
Assignees
Labels
enhancement New feature or request parser-kotlin

Comments

@knutwannheden
Copy link
Contributor

What problem are you trying to solve?

When modifying Java code the safest and often easiest way is to use JavaTemplate. For Kotlin this is currently not possible, because JavaTemplate uses a JavaParser (and not a KotlinParser) and there is no corresponding mechanism in rewrite-kotlin.

Describe the solution you'd like

Modify JavaTemplate (in rewrite-java) so that it can be provided with a KotlinParser rather than a JavaParser and then use this mechanism to parse context-free templates.

Supporting context-sensitive templates will be more work and will probably require a new KotlinTemplate type.

Have you considered any alternatives or workarounds?

Additional context

Are you interested in contributing this feature to OpenRewrite?

@knutwannheden knutwannheden added the enhancement New feature or request label Aug 14, 2023
@knutwannheden knutwannheden self-assigned this Aug 14, 2023
@knutwannheden knutwannheden moved this to In Progress in OpenRewrite Aug 14, 2023
knutwannheden added a commit to openrewrite/rewrite that referenced this issue Aug 14, 2023
To allow the `JavaTemplate` mechanism to be used for other languages like Kotlin, the provided parser builder must provide a way to add a classpath entry. This is because the internal `__M__` and `__P__` types are required for the parameter substitution and rather than including them as source code in the compilation unit, the parser will load them from the classpath.

To this end this PR introduces new `JvmParser` and `JvmParser.Builder` types and the `JavaParser.Builder#classpath()` methods are moved to `JvmParser.Builder`. In order to not increase the API surface area, no corresponding getter was added to `JvmParser.Builder`. Instead, there is a new `Internals` class providing a static `getClasspath(JvmParser.Builder)` method.

Issue: openrewrite/rewrite-kotlin#218
@nmck257
Copy link

nmck257 commented Dec 8, 2023

Hey @knutwannheden,
Naïve question: is there a possible implementation where a J tree (like from a JavaTemplate) is converted into a K tree?

This feels syntactically possible, would provide some level of compatibility for existing recipes written using JavaTemplate, and would also open up for features where OpenRewrite is used to translate code between languages.

@knutwannheden
Copy link
Contributor Author

This is indeed an interesting topic. While the Kotlin printer should be able to print a J tree (since K is an extension of J), the code would in many cases not be idiomatic Kotlin code and I am afraid it would in many cases not even be correct code. This then indeed requires some type of transformation.

We do have a concept for how a JavaVisitor can be adapted so that it can be adapted by a KotlinVisitor to also be able to process Kotlin LSTs, but we are still investigating how to best use this to make Java recipes applicable to Kotlin code. Further, this would not really help when a recipe uses JavaTemplate to emit new code.

We haven't yet worked out how exactly these things should all fit together, but we would definitely want as many Java recipes as possible to be compatible with Kotlin. Independent of this I think it makes sense to have a KotlinTemplate which allows Kotlin developers to more easily author Kotlin recipes.

@nmck257
Copy link

nmck257 commented Dec 9, 2023

Agreed, KotlinTemplate is valuable independent of any enhancements to make java recipes more effective on kotlin code.

And I think that starts to answer some of the questions I raised over here:

I suppose it wouldn't take much code to play with using the kotlin printer on a J tree on my machine; I'd be curious to see just how far it can be from valid (even ignoring idiomatic)

knutwannheden added a commit to openrewrite/rewrite that referenced this issue Mar 4, 2024
* Add new `JvmParser` as supertype to `JavaParser`

To allow the `JavaTemplate` mechanism to be used for other languages like Kotlin, the provided parser builder must provide a way to add a classpath entry. This is because the internal `__M__` and `__P__` types are required for the parameter substitution and rather than including them as source code in the compilation unit, the parser will load them from the classpath.

To this end this PR introduces new `JvmParser` and `JvmParser.Builder` types and the `JavaParser.Builder#classpath()` methods are moved to `JvmParser.Builder`. In order to not increase the API surface area, no corresponding getter was added to `JvmParser.Builder`. Instead, there is a new `Internals` class providing a static `getClasspath(JvmParser.Builder)` method.

Issue: openrewrite/rewrite-kotlin#218

* Correct bounds on `JvmParser.Builder`

* Make `JvmParser.Builder` constructor protected

* No need for initializer block when templating context-free expression

* Expose more of `JavaTemplate` engine API for extension

* Remove `JvmParser` and `Internals` again

* Make `Substitutions` extensible

* Lazily initialize `TEMPLATE_CLASSPATH_DIR` at runtime

* Add `BlockStatementTemplateGenerator#TEMPLATE_INTERNAL_IMPORTS`

* Correction to `Substitutions` after merging

* Rename new `addClasspath()` to `classpathEntry()`

* Remove unused `JavaTemplate#parameterCount`

* Update rewrite-java/src/main/java/org/openrewrite/java/internal/template/__M__.java

* Update rewrite-java/src/main/java/org/openrewrite/java/internal/template/__P__.java

* Revert accidental visibility change

* Fix problem with classpath in `JavaParser.Builder`
@timtebeek
Copy link
Contributor

@github-project-automation github-project-automation bot moved this from In Progress to Done in OpenRewrite Dec 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request parser-kotlin
Projects
Archived in project
Development

No branches or pull requests

4 participants