You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/topics/compiler-plugins.md
+78-4Lines changed: 78 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
This page explains the Kotlin compiler plugins available to you and what you can do if none of them suits your use case.
4
4
5
-
Compiler plugins hook into the compilation process to analyze or change code while it’s being compiled, without modifying the compiler itself. For example, they can annotate code or generate new code to make it compatible with other frameworks or APIs.
5
+
Compiler plugins hook into the compilation process to analyze or change code while it's being compiled, without modifying the compiler itself. For example, they can annotate code or generate new code to make it compatible with other frameworks or APIs.
6
6
7
7
The Kotlin team maintains the following compiler plugins:
8
8
*[All-open](all-open-plugin.md)
@@ -20,12 +20,12 @@ The Kotlin team maintains the following compiler plugins:
20
20
The Android team at Google maintains the [Compose compiler Gradle plugin](https://developer.android.com/develop/ui/compose/compiler)
21
21
and the [Parcelize plugin](https://plugins.gradle.org/plugin/org.jetbrains.kotlin.plugin.parcelize).
22
22
23
-
If you need to adapt the compilation process in a way that these plugins don’t cover, first check whether you can use the
23
+
If you need to adapt the compilation process in a way that these plugins don't cover, first check whether you can use the
24
24
[Kotlin Symbol Processing (KSP) API](https://kotlinlang.org/docs/ksp-overview.html) or an external linter such as [Android lint](https://developer.android.com/studio/write/lint).
25
25
You can browse our [Kotlin Slack](https://slack-chats.kotlinlang.org/c/compiler) or [reach out](https://surveys.jetbrains.com/s3/kotlin-slack-sign-up)
26
26
and ask for advice about your use case.
27
27
28
-
If you still can’t find what you need, you can create a custom compiler plugin. Use this approach only as a last resort,
28
+
If you _still_ can't find what you need, you can create a custom compiler plugin. Use this approach only as a last resort,
29
29
because the Kotlin compiler plugin API is **unstable**. Maintaining a custom compiler plugin requires significant ongoing
30
30
effort, since each new compiler release introduces breaking changes.
31
31
@@ -57,7 +57,7 @@ In practice, the most common compiler plugins affect the stages from analysis an
57
57
covering both frontend and backend. For example, the frontend part generates declarations, and the backend part adds
58
58
bodies for those declarations.
59
59
60
-
The [Kotlin serialization plugin](https://github.com/Kotlin/kotlinx.serialization) is a good example. The plugin’s
60
+
The [Kotlin serialization plugin](https://github.com/Kotlin/kotlinx.serialization) is a good example. The plugin's
61
61
frontend part adds a companion object and a serializer function, as well as checks to prevent name conflicts. The backend
62
62
part implements the desired serialization behavior through `KSerializer` objects.
63
63
@@ -85,3 +85,77 @@ extension points to customize resolution:
85
85
|[`FirStatusTransformerExtension`](https://github.com/JetBrains/kotlin/blob/master/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirStatusTransformerExtension.kt)| Modify declaration status attributes such as visibility or modality. |
86
86
|[`FirSupertypeGenerationExtension`](https://github.com/JetBrains/kotlin/blob/master/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/extensions/FirSupertypeGenerationExtension.kt)| Add new supertypes to an existing class. |
87
87
|[`FirTypeAttributeExtension`](https://github.com/JetBrains/kotlin/blob/master/compiler/fir/tree/src/org/jetbrains/kotlin/fir/extensions/FirTypeAttributeExtension.kt)| Add special attributes to certain types based on their type annotations. |
88
+
89
+
#### IDE integration
90
+
91
+
Each version of Intellij IDEA and Android Studio includes a developer version of the Kotlin compiler. This version is
92
+
specific to the IDE and is not binary compatible with the released Kotlin compiler. As a result, when you update your IDE,
93
+
your compiler plugin needs changes to work again. For this reason, community plugins aren't loaded by default.
94
+
95
+
To ensure that your custom compiler plugin works with different IDE versions, test it against each IDE version and fix
96
+
any issues you find.
97
+
98
+
Supporting multiple IDE versions could become easier if a devkit for Kotlin compiler plugins were available. If you're
99
+
interested in this feature, share your feedback in our [issue tracker](https://youtrack.jetbrains.com/issue/KT-82617).
100
+
101
+
### Backend plugin API
102
+
103
+
> Backend plugin development is difficult to do correctly without degrading IDE or debugger performance, so be careful
104
+
> and conservative with your changes.
105
+
>
106
+
{style="warning"}
107
+
108
+
The backend plugin API, also known as IR, has a single extension point: [`IrGenerationExtension`](https://github.com/JetBrains/kotlin/blob/master/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrGenerationExtension.kt).
109
+
Use this extension point and override the `generate()` function to add bodies to declarations already generated by the
110
+
frontend or change existing declaration bodies.
111
+
112
+
Changes made through this extension point are **not checked**. You must ensure that your changes don't break the compiler's
113
+
expectations at this stage. For example, you might accidentally introduce an invalid type, an incorrect function reference,
114
+
or a reference outside the correct scope.
115
+
116
+
#### Check your backend plugin for problems
117
+
118
+
You can check for problems in your backend plugin code in three main ways:
119
+
120
+
1.**Verify the IR**
121
+
122
+
Build the IR tree and enable the `Xverify-ir` compiler option. This option has a performance impact on compilation speed, so use it only during testing.
123
+
124
+
2.**Dump and compare IR output**
125
+
126
+
Create a dump file after the IR lowering compilation stage with the `-Xphases-to-dump-before=ExternalPackageParentPatcherLowering` compiler option. For the JVM backend, configure the dump directory with the `-Xdump-directory=<your-file-directory>` compiler option. Write the expected code manually, generate another dump file, and compare the two to see if there are differences.
127
+
128
+
3.**Debug the compiler code**
129
+
130
+
In the `convertToIr.kt` file, add breakpoints in the `convertToIrAndActualize()` function and run the compiler in debug mode to get more detailed information during compilation.
131
+
132
+
You can also explore the Kotlin serialization plugin code to see what backend plugin compiler code looks like in practice.
133
+
For example, [`SerializableCompanionIrGenerator.kt`](https://github.com/JetBrains/kotlin/blob/master/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt)
134
+
fills in missing bodies for key serializer members. One example is the [`generateChildSerializersGetter()`](https://github.com/JetBrains/kotlin/blob/9cfa558902abc13d245c825717026af63ef82dd2/plugins/kotlinx-serialization/kotlinx-serialization.backend/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt#L242)
135
+
function, which collects a list of `KSerializer` expressions and returns them in an array.
136
+
137
+
### Test your plugin
138
+
139
+
Once you implement your plugin, test it thoroughly. The [Kotlin compiler plugin template](https://github.com/Kotlin/compiler-plugin-template)
140
+
is already set up to use the [Kotlin compiler test framework](https://github.com/JetBrains/kotlin/blob/master/compiler/test-infrastructure/ReadMe.md).
141
+
You can add tests in the following directories:
142
+
143
+
*`compiler-plugin/testData`
144
+
*`compiler-plugin/testData/box` for code generation tests
145
+
*`compiler-plugin/testData/diagnostics` for diagnostic tests
146
+
147
+
When a test runs, the framework:
148
+
149
+
1. Parses the test source file. For example, [`anotherBoxTest.kt`](https://github.com/Kotlin/compiler-plugin-template/blob/master/compiler-plugin/testData/box/anotherBoxTest.kt)
150
+
2. Builds the FIR and IR for each file.
151
+
3. Writes these as textual dump files. For example, [`anotherBoxTest.fir.txt`](https://github.com/Kotlin/compiler-plugin-template/blob/master/compiler-plugin/testData/box/anotherBoxTest.fir.txt) and [`anotherBoxTest.fir.ir.txt`](https://github.com/Kotlin/compiler-plugin-template/blob/master/compiler-plugin/testData/box/anotherBoxTest.fir.ir.txt).
152
+
4. Compares these files with previously created files, if they exist.
153
+
154
+
You can use these files to check if any changes in the generated diff weren't intended. If there are no problems, the
155
+
new dump files become your latest _golden_ files: an approved and trusted source that you can compare future changes against.
156
+
157
+
### Get help
158
+
159
+
If you run into issues developing a custom compiler plugin, reach out in [Kotlin Slack](https://surveys.jetbrains.com/s3/kotlin-slack-sign-up)
160
+
in the [#compiler](https://kotlinlang.slack.com/archives/C7L3JB43G) channel. We can't promise a solution but we will try
0 commit comments