pseudo-kmp
GitHub指导在JPS环境中配置和使用伪KMP模块,涵盖插件注册、依赖限制、源文件夹设置及IML文件配置,以模拟expect/actual声明。
Trigger Scenarios
Install
npx skills add DetachHead/rebased --skill pseudo-kmp -g -y
SKILL.md
Frontmatter
{
"name": "pseudo-kmp",
"description": "Working with pseudo-KMP (Kotlin Multiplatform) modules in the IntelliJ monorepo. Use when creating, migrating, or modifying modules that use the expects-compiler-plugin for expect\/actual emulation in JPS projects."
}
Pseudo-KMP Modules
The monorepo is compiled by JPS, which does not support Kotlin Multiplatform. To emulate KMP expect/actual declarations, the Fleet team created the expects-compiler-plugin. This skill covers how to set up and work with modules that use this mechanism.
Documentation
- Multiplatform Migration Guide — step-by-step migration instructions
- Multiplatform Support README — compiler plugin usage and registration
- ExpectInMultiplatform.kt —
linkToActual()and@ActualAPI docs
Module Configuration Checklist
When creating or migrating a pseudo-KMP module:
-
Register in the structure test. Add your module name to the
multiplatformModuleslist incom.intellij.ideaProjectStructure.fast.MultiplatformModuleStructureTest(tests/ideaProjectStructure/testSrc/com/intellij/ideaProjectStructure/fast/MultiplatformModuleStructureTest.kt). -
Use only allowed library dependencies. The test enforces a closed set:
kotlin-stdlibkotlinx-coroutines-corekotlinx-coroutines-debugjetbrains-annotationskotlinx-serialization-corekotlinx-serialization-jsonkotlin-reflectkotlinx-collections-immutable
If you need a new library, add it to
allowedMultiplatformLibraryDependenciesin the test. Dependencies on other multiplatform modules (those inmultiplatformModules) are also allowed. -
Set up source folders:
src/— common codesrcJvm/orsrcJvmMain/— JVM-specific code (Java code can live here too)srcWasmJs/orsrcWasmJsMain/— WasmJs-specific codesrcJsMain/— JS-specific codesrcNativeMain/— Native-specific code
Important: Do NOT add
srcWasmJs/srcWasmJsMainas a source root in the.imlfile. The IDE would try to compile it in JVM mode. -
Add the
.pseudoCommonKotlinSourceSetmarker file to the common source root (e.g.,src/.pseudoCommonKotlinSourceSet). This empty file tells the Kotlin plugin that the source set is common code, preventing Optimize Imports from removing imports that are unnecessary on JVM but mandatory in common code (e.g.,@JvmStatic,@JvmField).
IML File Setup
Your .iml file needs two things: the multiplatformSupport dependency and the compiler plugin registration.
Use community/platform/util/multiplatform/intellij.platform.util.multiplatform.iml as a reference. To find the current plugin version, check that file rather than hardcoding.
1. Add the support module dependency (PROVIDED scope)
<orderEntry type="module" module-name="intellij.platform.multiplatformSupport" scope="PROVIDED" />
2. Add the Kotlin facet with expects-compiler-plugin
<facet type="kotlin-language" name="Kotlin">
<configuration version="5" platform="JVM 1.8" allPlatforms="JVM [1.8]" useProjectSettings="false">
<compilerSettings>
<option name="additionalArguments" value="-Xjvm-default=all ..." />
</compilerSettings>
<compilerArguments>
<stringArguments>
<stringArg name="jvmTarget" arg="1.8" />
<stringArg name="apiVersion" arg="2.3" />
<stringArg name="languageVersion" arg="2.3" />
</stringArguments>
<arrayArguments>
<arrayArg name="pluginClasspaths">
<args>$MAVEN_REPOSITORY$/jetbrains/fleet/expects-compiler-plugin/{VERSION}/expects-compiler-plugin-{VERSION}.jar</args>
</arrayArg>
</arrayArguments>
</compilerArguments>
</configuration>
</facet>
Replace {VERSION} with the version from the reference IML.
Expect/Actual Pattern
Only top-level functions are supported. Both the expect and actual declarations must be in the same module.
Common side (in src/)
Use linkToActual() as the function body:
import fleet.util.multiplatform.linkToActual
internal fun myFunction(param1: String, param2: Int): Boolean = linkToActual()
Platform side (in srcJvm/, srcWasmJs/, etc.)
Annotate with @Actual. The function name must be the expect function name + platform suffix:
import fleet.util.multiplatform.Actual
@Actual
internal fun myFunctionJvm(param1: String, param2: Int): Boolean {
// JVM implementation
}
Platform suffixes
| Platform | Suffix | Source folder |
|---|---|---|
| JVM | Jvm |
srcJvm/ or srcJvmMain/ |
| WasmJs | WasmJs |
srcWasmJs/ or srcWasmJsMain/ |
| JS | Js |
srcJsMain/ |
| Native | Native |
srcNativeMain/ |
| Multi-platform build | Impl |
(rare) |
Real example
Common (community/platform/util/base/multiplatform/src/com/intellij/util/text/CharArrayUtilKmp.kt):
internal fun getCharsPlatformSpecific(
sequence: CharSequence, srcOffset: Int, dst: CharArray, dstOffset: Int, len: Int
): Boolean = linkToActual()
JVM actual (community/platform/util/base/multiplatform/srcJvmMain/com/intellij/util/text/jvm.kt):
@Actual
internal fun getCharsPlatformSpecificJvm(
string: CharSequence, srcOffset: Int, dst: CharArray, dstOffset: Int, len: Int
): Boolean {
if (string is CharBuffer) { /* ... */ }
return false
}
Code Conversion Notes
- The monorepo uses the JVM version of the Kotlin standard library, which differs from the common version. Check which declarations are available in common code.
@JvmStatic,@JvmField, and similar annotations are not auto-imported in common code. Import them manually. The.pseudoCommonKotlinSourceSetmarker prevents the IDE from removing these imports.- Java code can remain in platform-specific source sets (
srcJvm/).
After Editing
- Run
./build/jpsModelToBazel.cmdafter modifying any.imlfiles. - Run
MultiplatformModuleStructureTestto validate module structure:./tests.cmd --module tests.ideaProjectStructure --test com.intellij.ideaProjectStructure.fast.MultiplatformModuleStructureTest - Lint changed files with
mcp__ijproxy__lint_files.
Artifact Publication
The monorepo does not publish multiplatform artifacts to Maven Central directly. Separate repositories with Gradle infrastructure extract module sources, compile with true KMP, and publish. See fleet-multiplatform-deps and fleet-parser-collection in JetBrains Space.
Version History
- 1f8708d Current 2026-08-16 15:39


