{"id":208182,"date":"2024-02-26T03:58:00","date_gmt":"2024-02-26T03:58:00","guid":{"rendered":"https:\/\/michigandigitalnews.com\/index.php\/2024\/02\/26\/kotlin-k2-and-standalone-source-generator\/"},"modified":"2025-06-25T17:21:35","modified_gmt":"2025-06-25T17:21:35","slug":"kotlin-k2-and-standalone-source-generator","status":"publish","type":"post","link":"https:\/\/michigandigitalnews.com\/index.php\/2024\/02\/26\/kotlin-k2-and-standalone-source-generator\/","title":{"rendered":"Kotlin K2 and Standalone Source Generator"},"content":{"rendered":"<p> [ad_1]<br \/>\n<\/p>\n<div>\n<meta content=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhZN8ICjCu1JRBCumZD-9CK6dV9Gq4fAkEe2lpsTao7njxZ64zVsBoWZc-UID_okfol4yS-AkKb2TPF0PT-7NvLw19xi9yoDRXSN0YfDZZuRbujrkpmVmB5u890diZPx0slqcAPeLxlK2oe1UAkY2IMdbD-NEwdHNHvyy_KPcrdBGuQ8Y4t6gALR69zyII\/s1600\/editorial-Ksp2-Preview-Kotlin-K2-social.png\" name=\"twitter:image\"\/><br \/>\n<img decoding=\"async\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhZN8ICjCu1JRBCumZD-9CK6dV9Gq4fAkEe2lpsTao7njxZ64zVsBoWZc-UID_okfol4yS-AkKb2TPF0PT-7NvLw19xi9yoDRXSN0YfDZZuRbujrkpmVmB5u890diZPx0slqcAPeLxlK2oe1UAkY2IMdbD-NEwdHNHvyy_KPcrdBGuQ8Y4t6gALR69zyII\/s1600\/editorial-Ksp2-Preview-Kotlin-K2-social.png\" style=\"display: none;\"\/><\/p>\n<p><em>Posted by Ting-Yuan Huang \u2013 Software Engineer, and Jiaxiang Chen \u2013 Software Engineer<br \/>\n<\/em><\/p>\n<p><a href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgciES-nL42T_uDeCEbNwdhYjKVh5FB9t8S-QJL8tr9eQu4h89A9fflFVFwEisju1Ii2g9YnRiHxgBoHNVzRFX_1W9pLqe2JP7vYYB0KmXeLt6LdQNa7IhwUvC_UXqEpKdOht_jG4yLQeVahycd8g_Zw2rxp6ccjFT97borB2Ivorh9yrHxhKZI9aqyLsw\/s1600\/Ksp2-Preview-Kotlin-K2-Banner.png\"><img decoding=\"async\" border=\"0\" data-original-height=\"800\" data-original-width=\"100%\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEgciES-nL42T_uDeCEbNwdhYjKVh5FB9t8S-QJL8tr9eQu4h89A9fflFVFwEisju1Ii2g9YnRiHxgBoHNVzRFX_1W9pLqe2JP7vYYB0KmXeLt6LdQNa7IhwUvC_UXqEpKdOht_jG4yLQeVahycd8g_Zw2rxp6ccjFT97borB2Ivorh9yrHxhKZI9aqyLsw\/s1600\/Ksp2-Preview-Kotlin-K2-Banner.png\"\/><\/a><\/p>\n<p>The Kotlin Symbol Processing (KSP) tool provides a high-level API for doing meta-programming in Kotlin.  Many tools have been built on KSP, enabling Kotlin code to be generated at compile time. For example, Jetpack Room uses KSP to generate code for accessing the database, based on an interface provided by the developer, like:<\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\">@Dao\n<span style=\"color: green; font-weight: bold;\">interface<\/span> UserDao {\n    @Query(<span style=\"color: #ba2121;\">\"SELECT * FROM user\"<\/span>)\n    <span style=\"color: green; font-weight: bold;\">fun<\/span> <span style=\"color: blue;\">getAll<\/span>(): List&lt;User&gt;\n}\n<\/pre>\n<\/div>\n<p>KSP provides the API to the Kotlin code so that Room in this case can generate the actual implementation of that interface.  While KSP has become a core foundation for meta-programing in Kotlin, its current implementation has some gaps which we are aiming to resolve with a new KSP2 architecture.  This blog details those architectural changes and the impact for plugins built on KSP.<\/p>\n<p>In addition, KSP2 has preview support for:<\/p>\n<ul>\n<ul>\n<li>The new Kotlin compiler (code-named K2)<\/li>\n<li>A new standalone source generator that provides more flexibility and features than the current Kotlin compiler plugin<\/li>\n<\/ul>\n<\/ul>\n<p>After getting feedback on the new architecture and continuing to address gaps we will work towards releasing KSP 2.0 where these changes will be the default.<\/p>\n<h3>Enabling the KSP2 Preview<\/h3>\n<p>The new preview changes can be enabled in KSP 1.0.14 or newer using a flag in <span style=\"color: #0d904f; font-family: courier;\">gradle.properties<\/span>:<\/p>\n<p>Note: You might need to enlarge the heap size of the Gradle daemon now that KSP and processors run in the Gradle daemon instead of the Kotlin compiler\u2019s daemon (which has larger default heap size), e.g. <span style=\"color: #0d904f; font-family: courier;\">org.gradle.jvmargs=-Xmx4096M -XX:MaxMetaspaceSize=1024m<\/span><\/p>\n<h3>KSP2 and K2<\/h3>\n<p>Internally KSP2 uses the Beta Kotlin K2 compiler (which will be the default compiler in Kotlin 2.0).  You can use KSP2 before switching your Kotlin compiler to K2 (via the <span style=\"color: #0d904f; font-family: courier;\">languageVersion<\/span> setting) but if you want to use K2 for compiling your code, check out: <a href=\"https:\/\/android-developers.googleblog.com\/2023\/07\/try-k2-compiler-in-your-android-projects.html\" target=\"_blank\" rel=\"noopener\">Try the K2 compiler in your Android projects<\/a>.<\/p>\n<h3>Standalone Source Generator<\/h3>\n<p>KSP1 is implemented as a Kotlin 1.x compiler plugin. Running KSP requires running the compiler and specifying KSP and its plugin options. In Gradle, KSP\u2019s tasks are customized compilation tasks, which dispatch real work to <span style=\"color: #0d904f; font-family: courier;\">KotlinCompileDaemon<\/span> by default. This makes debugging and testing somewhat difficult, because <span style=\"color: #0d904f; font-family: courier;\">KotlinCompileDaemon<\/span> runs in its own process, outside of Gradle.<\/p>\n<p>In KSP2, the implementation can be thought of as a library with a main entry point. Build systems and tools can call KSP with this entry point, without setting up the compiler. This makes it very easy to call KSP programmatically and is very useful especially for debugging and testing.  With KSP2 you can set breakpoints in KSP processors without having to perform any other \/ irregular setup tasks to enable debugging.<\/p>\n<p>Everything becomes much easier because KSP2 now controls its lifecycle and can be called as a standalone program or programmatically, like:<\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span style=\"color: green; font-weight: bold;\">val<\/span> kspConfig = KSPJvmConfig.Builder().apply {\n  <span style=\"color: #408080; font-style: italic;\">\/\/ All configurations happen here.<\/span>\n}.build()\n<span style=\"color: green; font-weight: bold;\">val<\/span> exitCode = KotlinSymbolProcessing(kspConfig, listOfProcessors, kspLoggerImpl).execute()\n<\/pre>\n<\/div>\n<h3>KSP2 API Behavior Changes<\/h3>\n<p>With the new implementation, it is also a great opportunity to introduce some refinements in the API behavior so that developers building on KSP will be more productive, have better debuggability and error recovery. For example, when resolving <span style=\"color: #0d904f; font-family: courier;\">Map<\/span><span style=\"color: #0d904f; font-family: courier;\">&lt;<\/span><span style=\"color: #0d904f; font-family: courier;\">String,<\/span> <span style=\"color: #0d904f; font-family: courier;\">NonExistentType<\/span><span style=\"color: #0d904f; font-family: courier;\">&gt;<\/span>, KSP1 simply returns an error type. In KSP2, <span style=\"color: #0d904f; font-family: courier;\">Map<\/span><span style=\"color: #0d904f; font-family: courier;\">&lt;<\/span><span style=\"color: #0d904f; font-family: courier;\">String,<\/span> <span style=\"color: #0d904f; font-family: courier;\">ErrorType<\/span><span style=\"color: #0d904f; font-family: courier;\">&gt;<\/span> will be returned instead.  Here is a list of the current API behavior changes we plan on making in KSP2:<\/p>\n<ol>\n<li>Resolve implicit type from function call: <span style=\"color: #0d904f; font-family: courier;\">val error = mutableMapOf<\/span><span style=\"color: #0d904f; font-family: courier;\">&lt;<\/span><span style=\"color: #0d904f; font-family: courier;\">String, NonExistType&gt;()<\/span>\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span> The whole type will be an error type due to failed type resolution<\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span> It will successfully resolve the container type, and for the non-existent type in the type argument, it will correctly report errors on the specific type argument.<\/p>\n<\/li>\n<li>Unbounded type parameter\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span> No bounds<\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span> An upper bound of <span style=\"color: #0d904f; font-family: courier;\">Any?<\/span> is always inserted for consistency<\/p>\n<\/li>\n<li>Resolving references to type aliases in function types and annotations\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span> Expanded to the underlying, non-alias type<\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span> Not expanded, like uses in other places.<\/p>\n<\/li>\n<li>Fully qualified names\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span> Constructors have FQN if the constructor is from source, but not if the constructor is from a library.<\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span> Constructors do not have FQN<\/p>\n<\/li>\n<li>Type arguments of inner types\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span> Inner types has arguments from outer types<\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span> Inner types has no arguments from outer types<\/p>\n<\/li>\n<li>Type arguments of star projections\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span> Star projections have type arguments that are expanded to the effective variances according to the declaration sites.<\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span> No expansion. Star projections have <span style=\"color: #0d904f; font-family: courier;\">null<\/span>s in their type arguments.<\/p>\n<\/li>\n<li>Variance of Java Array\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span> Java Array has a invariant upper bound<\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span> Java Array has a covariant upper bound<\/p>\n<\/li>\n<li>Enum entries\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span> An enum entry has its own subtype with a supertype of the enum class (incorrect behavior from language point of view)<\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span> An enum entry&#8217;s type is the type of the enclosing enum class<\/p>\n<\/li>\n<li>Multi-override scenario\n<p>For example<\/p>\n<div style=\"background: rgb(248, 248, 248); border: 0px; overflow: auto; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0px;\"><span style=\"color: green; font-weight: bold;\">interface<\/span> GrandBaseInterface1 {\n    <span style=\"color: green; font-weight: bold;\">fun<\/span> <span style=\"color: blue;\">foo<\/span>(): Unit\n}\n\n<span style=\"color: green; font-weight: bold;\">interface<\/span> GrandBaseInterface2 {\n    <span style=\"color: green; font-weight: bold;\">fun<\/span> <span style=\"color: blue;\">foo<\/span>(): Unit\n}\n\n<span style=\"color: green; font-weight: bold;\">interface<\/span> BaseInterface1 : GrandBaseInterface1 {\n}\n\n<span style=\"color: green; font-weight: bold;\">interface<\/span> BaseInterface2 : GrandBaseInterface2 {\n}\n\n<span style=\"color: green; font-weight: bold;\">class<\/span> <span style=\"color: blue; font-weight: bold;\">OverrideOrder1<\/span> : BaseInterface1, GrandBaseInterface2 {\n    <span style=\"color: green; font-weight: bold;\">override<\/span> <span style=\"color: green; font-weight: bold;\">fun<\/span> <span style=\"color: blue;\">foo<\/span>() = TODO()\n}\n<span style=\"color: green; font-weight: bold;\">class<\/span> <span style=\"color: blue; font-weight: bold;\">OverrideOrder2<\/span> : BaseInterface2, GrandBaseInterface1 {\n    <span style=\"color: green; font-weight: bold;\">override<\/span> <span style=\"color: green; font-weight: bold;\">fun<\/span> <span style=\"color: blue;\">foo<\/span>() = TODO()\n}\n<\/pre>\n<\/div>\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span><\/p>\n<div>Find overridden symbols in BFS order, first super type found on direct super type list that contains overridden symbol is returned<br \/>\nFor the example, KSP will say <span style=\"color: #0d904f; font-family: courier;\">OverrideOrder1.foo()<\/span> overrides <span style=\"color: #0d904f; font-family: courier;\">GrandBaseInterface2.foo()<\/span> and <span style=\"color: #0d904f; font-family: courier;\">OverrideOrder2.foo()<\/span> overrides <span style=\"color: #0d904f; font-family: courier;\">GrandBaseInterface1.foo()<\/span><\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span><\/p>\n<p>DFS order, first super type found overridden symbols (with recursive super type look up) in direct super type list is returned.<\/p>\n<p>For the example, KSP will say <span style=\"color: #0d904f; font-family: courier;\">OverrideOrder1.foo()<\/span> overrides <span style=\"color: #0d904f; font-family: courier;\">GrandBaseInterface1.foo()<\/span> and <span style=\"color: #0d904f; font-family: courier;\">OverrideOrder2.foo()<\/span> overrides <span style=\"color: #0d904f; font-family: courier;\">GrandBaseInterface2.foo()<\/span><\/p>\n<\/div>\n<\/li>\n<li>Java modifier\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span> Transient\/volatile fields are final by default<\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span> Transient\/volatile fields are open by default<\/p>\n<\/li>\n<li>Type annotations\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span> Type annotations on a type argument is only reflected on the type argument symbol<\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span> Type annotations on a type argument now present in the resolved type as well<\/p>\n<\/li>\n<li><span style=\"color: #0d904f; font-family: courier;\">vararg<\/span> parameters\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span> Considered an Array type<\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span> Not considered an <span style=\"color: #0d904f; font-family: courier;\">Array<\/span> type<\/p>\n<\/li>\n<li>Synthesized members of Enums\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span> <span style=\"color: #0d904f; font-family: courier;\">values<\/span> and <span style=\"color: #0d904f; font-family: courier;\">valueOf<\/span> are missing if the enum is defined in Kotlin sources<\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span> <span style=\"color: #0d904f; font-family: courier;\">values<\/span> and <span style=\"color: #0d904f; font-family: courier;\">valueOf<\/span> are always present<\/p>\n<\/li>\n<li>Synthesized members of data classes\n<p><span style=\"color: #ffa400;\"><b>KSP1:<\/b><\/span> <span style=\"color: #0d904f; font-family: courier;\">componentN<\/span> and <span style=\"color: #0d904f; font-family: courier;\">copy<\/span> are missing if the data class is defined in Kotlin sources<\/p>\n<p><span style=\"color: #4285f4;\"><b>KSP2:<\/b><\/span> <span style=\"color: #0d904f; font-family: courier;\">componentN<\/span> and <span style=\"color: #0d904f; font-family: courier;\">copy<\/span> are always present<\/p>\n<\/li>\n<\/ol>\n<h3>New Multiplatform Processing Scheme<\/h3>\n<p>When it comes to the processing scheme, i.e. what sources are processed when, the principle of KSP is to be consistent with the build&#8217;s existing compilation scheme. In other words, what the compiler sees is what processors see, plus the source code that is generated by processors.<\/p>\n<div align=\"center\" dir=\"ltr\" style=\"margin-left: 0pt;\">\n<table style=\"border-collapse: collapse; border: none;\">\n<thead>\n<tr style=\"height: 0pt;\">\n<th scope=\"col\" style=\"border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;\">\n                    <span style=\"font-weight: normal;\">What processors see<\/span>\n                <\/th>\n<th scope=\"col\" style=\"border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;\"><span style=\"font-weight: normal;\">Kotlin compiler see<br \/>\n                    <\/span><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr style=\"height: 23.7979pt;\">\n<td style=\"border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;\">ClassA.kt, UtilB.kt, InterfaceC.kt &#8230; <\/td>\n<td style=\"border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;\">ClassA.kt, UtilB.kt, InterfaceC.kt &#8230; + GeneratedFromA.kt, &#8230;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>In KSP1&#8217;s current compilation scheme, common \/ shared source sets are processed and compiled multiple times, with each target. For example, <span style=\"color: #0d904f; font-family: courier;\">commonMain<\/span> is processed and compiled 3 times in the following project layout. Being able to process all the sources from dependencies is convenient with one exception: Processors don\u2019t see the sources generated from <span style=\"color: #0d904f; font-family: courier;\">commonMain<\/span> when processing <span style=\"color: #0d904f; font-family: courier;\">jvmMain<\/span> and <span style=\"color: #0d904f; font-family: courier;\">jsMain<\/span>. Everything must be re-processed and that can be inefficient.<\/p>\n<p><image><\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" alt=\"Flow diagram illustrating sources generated from jvmMain and jsMain processing to commonMain\" border=\"0\" id=\"imgCaption\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhw35G_18k1-mq1xccgFm3Ibp3qEcYk5Yx7HGBYdz-bRMhlsZ919E-7Xk0t8iYAf3dbnjOylYY-YJbFv_64xeYN6UIyKy9mCvKiK5OexUtn6wqY3WDvyIW0JknxVNnuUHC1NxSioSVpTyG_AkaidpFD6IKTD7zGNp_hhCAQdHZ8yPKvcxMgI5_93I-gfjs\/s1600\/Ksp2-Preview-Kotlin-Chart.png\" width=\"75%\"\/><\/div>\n<p><\/image><\/p>\n<div align=\"center\">\n<table style=\"border-collapse: collapse; border: none; margin-right: calc(0%); width: 100%;\">\n<tbody>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 41.4768%;\">\n<p><span style=\"font-size: 11pt;\">tasks<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 29.8571%;\">\n<p><span style=\"font-size: 11pt;\">inputs<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 28.4867%;\">\n<p><span style=\"font-size: 11pt;\">outputs<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 41.4768%;\">\n<p><span style=\"font-size: 11pt;\">kspKotlinCommonMainMetadata<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 29.8571%;\">\n<p><span style=\"font-size: 11pt;\">commonMain<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 28.4867%;\">\n<p><span style=\"font-size: 11pt;\">generatedCommon<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 41.4768%;\">\n<p><span style=\"font-size: 11pt;\">kspKotlinJvm<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 29.8571%;\">\n<p><span style=\"font-size: 11pt;\">commonMain, jvmMain<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 28.4867%;\">\n<p><span style=\"font-size: 11pt;\">generatedCommonJvm<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 41.4768%;\">\n<p><span style=\"font-size: 11pt;\">kspKotlinJs<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 29.8571%;\">\n<p><span style=\"font-size: 11pt;\">commonMain, jsMain<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 28.4867%;\">\n<p><span style=\"font-size: 11pt;\">generatedCommonJs<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 41.4768%;\">\n<p><span style=\"font-size: 11pt;\">compileKotlinCommonMainMetadata<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 29.8571%;\">\n<p><span style=\"font-size: 11pt;\">commonaMain, generatedCommon<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 28.4867%;\">\n<p><span style=\"font-size: 11pt;\">common.klib<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 41.4768%;\">\n<p><span style=\"font-size: 11pt;\">compileKotlinJvm<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 29.8571%;\">\n<p><span style=\"font-size: 11pt;\">commonMain, jvmMain, generatedCommonJvm<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 28.4867%;\">\n<p><span style=\"font-size: 11pt;\">app.jar<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 41.4768%;\">\n<p><span style=\"font-size: 11pt;\">compileKotlinJs<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 29.8571%;\">\n<p><span style=\"font-size: 11pt;\">commonMain, jsMain, generatedCommonJs<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 28.4867%;\">\n<p><span style=\"font-size: 11pt;\">main.js<\/span><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>In KSP2, we plan to add an experimental mode that tries to align to <a href=\"https:\/\/youtrack.jetbrains.com\/issue\/KT-61506\/Multiplatform-Separate-common-resolution-in-K2\" target=\"_blank\" rel=\"noopener\">how source sets are compiled in K2<\/a> better. All sources can be processed only once with the available new processing scheme:<\/p>\n<div align=\"center\">\n<table style=\"border-collapse: collapse; border: none;\">\n<tbody>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 34%;\">\n<p><span style=\"font-size: 9.5pt;\">tasks<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 22%;\">\n<p><span style=\"font-size: 9.5pt;\">inputs<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 19%;\">\n<p><span style=\"font-size: 9.5pt;\">outputs<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 25%;\">\n<p><span style=\"font-size: 9.5pt;\">Resolvable but not available in\u00a0<\/span><\/p>\n<p><span style=\"color: #188038; font-family: courier; font-size: 10pt;\">getAllFiles<\/span><span style=\"font-size: 10pt;\">\u00a0\/\u00a0<\/span><\/p>\n<p><span style=\"color: #188038; font-family: courier; font-size: 10pt;\">getSymbolsWithAnnotation<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 34%;\">\n<p><span style=\"font-size: 9.5pt;\">kspKotlinCommonMainMetadata<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 22%;\">\n<p><span style=\"font-size: 9.5pt;\">commonMain<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 20%;\">\n<p><span style=\"font-size: 9.5pt;\">generatedCommon<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 24%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 34%;\">\n<p><span style=\"font-size: 9.5pt;\">kspKotlinJvm<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 22%;\">\n<p><span style=\"font-size: 9.5pt;\">jvmMain<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 20%;\">\n<p><span style=\"font-size: 9.5pt;\">generatedJvm<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 24%;\">\n<p><span style=\"font-size: 9.5pt;\">commonMain, generatedCommon<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 34%;\">\n<p><span style=\"font-size: 9.5pt;\">kspKotlinJs<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 22%;\">\n<p><span style=\"font-size: 9.5pt;\">jsMain<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 20%;\">\n<p><span style=\"font-size: 9.5pt;\">generatedJs<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 24%;\">\n<p><span style=\"font-size: 9.5pt;\">commonaMain, generatedCommon<\/span><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 34%;\">\n<p><span style=\"font-size: 9.5pt;\">compileKotlinCommonMainMetadata<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 22%;\">\n<p><span style=\"font-size: 9.5pt;\">commonaMain, generatedCommon<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 20%;\">\n<p><span style=\"font-size: 9.5pt;\">common.klib<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 24%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 34%;\">\n<p><span style=\"font-size: 9.5pt;\">compileKotlinJvm<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 22%;\">\n<p><span style=\"font-size: 9.5pt;\">commonMain, jvmMain, generatedCommon, generatedJvm<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 20%;\">\n<p><span style=\"font-size: 9.5pt;\">app.jar<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 24%;\"><\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 34%;\">\n<p><span style=\"font-size: 9.5pt;\">compileKotlinJs<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 22%;\">\n<p><span style=\"font-size: 9.5pt;\">commonMain, jsMain, generatedCommon, generatedJs<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 20%;\">\n<p><span style=\"font-size: 9.5pt;\">main.js<\/span><\/p>\n<\/td>\n<td style=\"border: 1pt solid rgb(0, 0, 0); width: 24%;\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>Please note that Kotlin 2.0 is still in beta and the compilation model is subject to change. Please let us know how this works for you and give us <a href=\"https:\/\/github.com\/google\/ksp\/issues\" target=\"_blank\" rel=\"noopener\">feedback<\/a>.<\/p>\n<h3>KSP2 Preview Feedback<\/h3>\n<p>KSP2 is in preview but there is still more <a href=\"https:\/\/github.com\/google\/ksp\/milestone\/24\" target=\"_blank\" rel=\"noopener\">work to be done<\/a> before a stable release.  We hope these new features will ultimately help you be more productive when using KSP!  Please provide us with your <a href=\"https:\/\/github.com\/google\/ksp\/issues\" target=\"_blank\" rel=\"noopener\">feedback<\/a> so we can make these improvements awesome as they progress towards being stable.<\/p>\n<\/div>\n<p>[ad_2]<br \/>\n<br \/><a href=\"http:\/\/android-developers.googleblog.com\/2023\/12\/ksp2-preview-kotlin-k2-standalone.html\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[ad_1] Posted by Ting-Yuan Huang \u2013 Software Engineer, and Jiaxiang Chen \u2013 Software Engineer The Kotlin Symbol Processing (KSP) tool provides a high-level API for<\/p>\n","protected":false},"author":1,"featured_media":208183,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[146],"tags":[],"_links":{"self":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/208182"}],"collection":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/comments?post=208182"}],"version-history":[{"count":2,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/208182\/revisions"}],"predecessor-version":[{"id":342153,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/208182\/revisions\/342153"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media\/208183"}],"wp:attachment":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media?parent=208182"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/categories?post=208182"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/tags?post=208182"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}