Skip to content

Commit 4d224ea

Browse files
committed
~
1 parent 46d47e4 commit 4d224ea

File tree

21 files changed

+369
-186
lines changed

21 files changed

+369
-186
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ tasks.withType<KotlinCompile> {
129129
}
130130
dependsOn(":executors:jar")
131131
dependsOn(":indexation:run")
132+
dependsOn(":cache-maker:run")
132133
buildPropertyFile()
133134
}
134135
println("Using Kotlin compiler ${libs.versions.kotlin.get()}")

cache-maker/build.gradle.kts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
plugins {
2+
kotlin("jvm")
3+
application
4+
}
5+
6+
dependencies {
7+
implementation(project(":common", configuration = "default"))
8+
}
9+
10+
application {
11+
mainClass.set("cache.MainKt")
12+
}
13+
14+
tasks.withType<JavaExec> {
15+
dependsOn(":dependencies:copyDependencies")
16+
dependsOn(":dependencies:copyWasmDependencies")
17+
dependsOn(":dependencies:copyComposeWasmCompilerPlugins")
18+
dependsOn(":dependencies:copyComposeWasmDependencies")
19+
20+
val rootName = project.rootProject.projectDir.toString()
21+
22+
val kotlinVersion = libs.versions.kotlin.get()
23+
inputs.property("kotlinVersion", kotlinVersion)
24+
25+
// Adding classpath directories as task input for up-to-date checks
26+
inputs.dir(libWasmFolder)
27+
inputs.dir(libComposeWasmFolder)
28+
inputs.dir(libComposeWasmCompilerPluginsFolder)
29+
30+
// Adding resulting index files as output for up-to-date checks
31+
val composeCacheComposeWasm = "$rootName${File.separator}$cachesComposeWasm"
32+
outputs.dir(cachesComposeWasmFolder)
33+
34+
debugOptions {
35+
enabled = true
36+
port = 5005
37+
server = true
38+
suspend = false
39+
}
40+
41+
args = listOf(
42+
kotlinVersion,
43+
libJVMFolder.asFile.absolutePath,
44+
composeCacheComposeWasm,
45+
)
46+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import com.compiler.server.common.components.KotlinEnvironment
2+
import com.compiler.server.common.components.compileWasmArgs
3+
import com.compiler.server.common.components.linkWasmArgs
4+
import com.compiler.server.common.components.usingTempDirectory
5+
import org.jetbrains.kotlin.cli.common.CLICompiler.Companion.doMainNoExit
6+
import org.jetbrains.kotlin.cli.js.K2JSCompiler
7+
import java.io.File
8+
import kotlin.io.path.div
9+
10+
11+
class CacheBuilder(
12+
private val kotlinEnvironment: KotlinEnvironment,
13+
) {
14+
fun compileCache(outputForCache: String) {
15+
val moduleName = "moduleId"
16+
usingTempDirectory { outputDir ->
17+
val resource = this::class.java.classLoader.getResource("File.kt")!!.path
18+
19+
val klibPath = (outputDir / "klib").toFile().normalize().absolutePath
20+
21+
val k2JSCompiler = K2JSCompiler()
22+
23+
doMainNoExit(
24+
k2JSCompiler,
25+
compileWasmArgs(
26+
moduleName,
27+
listOf(resource),
28+
klibPath,
29+
kotlinEnvironment.COMPOSE_WASM_COMPILER_PLUGINS,
30+
kotlinEnvironment.composeWasmCompilerPluginOptions,
31+
kotlinEnvironment.COMPOSE_WASM_LIBRARIES
32+
).toTypedArray()
33+
)
34+
35+
usingTempDirectory { tmpDir ->
36+
val cachesDir = tmpDir.resolve("caches").normalize()
37+
doMainNoExit(
38+
k2JSCompiler,
39+
linkWasmArgs(
40+
moduleName,
41+
klibPath,
42+
kotlinEnvironment.COMPOSE_WASM_LIBRARIES,
43+
cachesDir.normalize(),
44+
outputDir,
45+
false
46+
).toTypedArray()
47+
)
48+
49+
cachesDir.toFile().copyRecursively(File(outputForCache), overwrite = true)
50+
}
51+
}
52+
}
53+
}

cache-maker/src/main/kotlin/Main.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package cache
2+
3+
import CacheBuilder
4+
import com.compiler.server.common.components.KotlinEnvironmentConfiguration
5+
6+
fun main(args: Array<String>) {
7+
val version = args[0]
8+
val directory = args[1]
9+
val outputPathCacheComposeWasm = args[2]
10+
val kotlinEnvironment = KotlinEnvironmentConfiguration(version, directory).kotlinEnvironment
11+
12+
CacheBuilder(
13+
kotlinEnvironment = kotlinEnvironment
14+
).compileCache(outputPathCacheComposeWasm)
15+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import androidx.compose.animation.AnimatedVisibility
2+
import androidx.compose.foundation.layout.Column
3+
import androidx.compose.foundation.layout.fillMaxWidth
4+
import androidx.compose.material.Button
5+
import androidx.compose.material.MaterialTheme
6+
import androidx.compose.material.Text
7+
import androidx.compose.runtime.*
8+
import androidx.compose.ui.Alignment
9+
import androidx.compose.ui.ExperimentalComposeUiApi
10+
import androidx.compose.ui.Modifier
11+
12+
//sampleStart
13+
@OptIn(ExperimentalComposeUiApi::class)
14+
fun main() {
15+
println("Hello")
16+
}
17+
18+
@Composable
19+
fun App() {
20+
MaterialTheme {
21+
var greetingText by remember { mutableStateOf("Hello World!") }
22+
var showImage by remember { mutableStateOf(false) }
23+
var counter by remember { mutableStateOf(0) }
24+
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
25+
Button(onClick = {
26+
counter++
27+
greetingText = "Compose: ${Greeting().greet()}"
28+
showImage = !showImage
29+
}) {
30+
Text(greetingText)
31+
}
32+
AnimatedVisibility(showImage) {
33+
Text(counter.toString())
34+
}
35+
}
36+
}
37+
}
38+
39+
private val platform = object : Platform {
40+
41+
override val name: String
42+
get() = "Web with Kotlin/Wasm"
43+
}
44+
45+
fun getPlatform(): Platform = platform
46+
47+
class Greeting {
48+
private val platform = getPlatform()
49+
50+
fun greet(): String {
51+
return "Hello, ${platform.name}!"
52+
}
53+
}
54+
55+
interface Platform {
56+
val name: String
57+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.compiler.server.common.components
2+
3+
import java.io.File
4+
import java.nio.file.Path
5+
import java.util.*
6+
import kotlin.io.path.*
7+
8+
@OptIn(ExperimentalPathApi::class)
9+
fun <T> usingTempDirectory(action: (path: Path) -> T): T {
10+
val path = getTempDirectory()
11+
path.createDirectories()
12+
return try {
13+
action(path)
14+
} finally {
15+
path.deleteRecursively()
16+
}
17+
}
18+
19+
private fun getTempDirectory(): Path {
20+
val dir = System.getProperty("java.io.tmpdir")
21+
val sessionId = UUID.randomUUID().toString().replace("-", "")
22+
return File(dir).canonicalFile.resolve(sessionId).toPath()
23+
}
24+
25+
fun compileWasmArgs(
26+
moduleName: String,
27+
filePaths: List<String>,
28+
klibPath: String,
29+
compilerPlugins: List<String>,
30+
compilerPluginOptions: List<String>,
31+
dependencies: List<String>,
32+
): List<String> {
33+
val compilerPluginsArgs: List<String> = compilerPlugins
34+
.takeIf { it.isNotEmpty() }
35+
?.let { plugins ->
36+
plugins.map {
37+
"-Xplugin=$it"
38+
} + compilerPluginOptions.map {
39+
"-P=$it"
40+
}
41+
} ?: emptyList()
42+
val additionalCompilerArgumentsForKLib: List<String> = listOf(
43+
"-Xreport-all-warnings",
44+
"-Xuse-fir-extended-checkers",
45+
"-Xwasm",
46+
"-Xir-produce-klib-dir",
47+
"-libraries=${dependencies.joinToString(PATH_SEPARATOR)}",
48+
"-ir-output-dir=$klibPath",
49+
"-ir-output-name=$moduleName",
50+
) + compilerPluginsArgs
51+
52+
return filePaths + additionalCompilerArgumentsForKLib
53+
}
54+
55+
fun linkWasmArgs(
56+
moduleName: String,
57+
klibPath: String,
58+
dependencies: List<String>,
59+
icDir: Path?,
60+
outputDir: Path,
61+
debugInfo: Boolean,
62+
): List<String> {
63+
return mutableListOf(
64+
"-Xreport-all-warnings",
65+
"-Xuse-fir-extended-checkers",
66+
"-Xwasm",
67+
"-Xir-produce-js",
68+
"-Xinclude=$klibPath",
69+
"-libraries=${dependencies.joinToString(PATH_SEPARATOR)}",
70+
"-ir-output-dir=${(outputDir / "wasm").toFile().canonicalPath}",
71+
"-ir-output-name=$moduleName",).also {
72+
if (debugInfo) it.add("-Xwasm-generate-wat")
73+
74+
if (icDir != null) {
75+
it.add("-Xcache-directory=${icDir.normalize().absolutePathString()}")
76+
} else {
77+
it.add("-Xir-dce")
78+
}
79+
}
80+
}
81+
82+
val PATH_SEPARATOR: String = File.pathSeparator

common/src/main/kotlin/component/KotlinEnvironment.kt renamed to common/src/main/kotlin/com/compiler/server/common/components/KotlinEnvironment.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
package component
1+
package com.compiler.server.common.components
22

33
import com.intellij.openapi.util.Disposer
4+
import component.CompilerPluginOption
45
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
56
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
67
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
@@ -70,13 +71,13 @@ class KotlinEnvironment(
7071
.map { it.absolutePath }
7172
.filter { isKotlinLibrary(File(it)) }
7273
val WASM_LIBRARIES = additionalWasmClasspath
73-
.map { it.absolutePath }
74+
.map { it.path }
7475
.filter { isKotlinLibrary(File(it)) }
7576
val COMPOSE_WASM_LIBRARIES = additionalComposeWasmClasspath
76-
.map { it.absolutePath }
77+
.map { it.path }
7778
.filter { isKotlinLibrary(File(it)) }
7879
val COMPOSE_WASM_COMPILER_PLUGINS = composeWasmCompilerPlugins
79-
.map { it.absolutePath }
80+
.map { it.path }
8081

8182
val composeWasmCompilerPluginOptions = composeWasmCompilerPluginsOptions
8283
.map { "plugin:${it.id}:${it.option}=${it.value}" }

indexation/src/main/kotlin/KotlinEnvironmentConfiguration.kt renamed to common/src/main/kotlin/com/compiler/server/common/components/KotlinEnvironmentConfiguration.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
package indexation
1+
package com.compiler.server.common.components
22

33
import component.CompilerPluginOption
4-
import component.KotlinEnvironment
54
import java.io.File
65

76
class KotlinEnvironmentConfiguration(

dependencies/build.gradle.kts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,44 @@ val kotlinComposeWasmDependency: Configuration by configurations.creating {
6060
}
6161
}
6262

63+
val kotlinComposeWasmIcCache: Configuration by configurations.creating {
64+
isTransitive = false
65+
attributes {
66+
attribute(
67+
KotlinPlatformType.attribute,
68+
KotlinPlatformType.wasm
69+
)
70+
attribute(
71+
KotlinWasmTargetAttribute.wasmTargetAttribute,
72+
KotlinWasmTargetAttribute.js
73+
)
74+
attribute(
75+
LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
76+
objects.named(LibraryElements::class.java, "compose-wasm-cache")
77+
)
78+
}
79+
}
80+
81+
val kotlinComposeWasmCopied: Configuration by configurations.creating {
82+
isCanBeResolved = false
83+
isCanBeConsumed = true
84+
85+
attributes {
86+
attribute(
87+
KotlinPlatformType.attribute,
88+
KotlinPlatformType.wasm
89+
)
90+
attribute(
91+
KotlinWasmTargetAttribute.wasmTargetAttribute,
92+
KotlinWasmTargetAttribute.js
93+
)
94+
attribute(
95+
LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
96+
objects.named(LibraryElements::class.java, "compose-wasm-copied")
97+
)
98+
}
99+
}
100+
63101
val composeWasmCompilerPlugins: Configuration by configurations.creating {
64102
isTransitive = false
65103
}
@@ -96,6 +134,15 @@ val copyComposeWasmCompilerPlugins by tasks.creating(Copy::class) {
96134
into(libComposeWasmCompilerPluginsFolder)
97135
}
98136

137+
//val copyComposeWasmIcCaches by tasks.creating(Copy::class) {
138+
// from(kotlinComposeWasmIcCache)
139+
// into(cachesComposeWasmFolder)
140+
//}
141+
142+
artifacts.add(kotlinComposeWasmCopied.name, libComposeWasmFolder) {
143+
builtBy(copyComposeWasmDependencies)
144+
}
145+
99146
plugins {
100147
kotlin("jvm")
101148
}
@@ -124,4 +171,6 @@ dependencies {
124171
kotlinComposeWasmDependency(libs.bundles.compose)
125172

126173
composeWasmCompilerPlugins(libs.kotlin.compose.compiler.plugin)
174+
175+
kotlinComposeWasmIcCache(project(":cache-maker"))
127176
}

indexation/src/main/kotlin/JvmIndexationBuilder.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package indexation
22

3+
import com.compiler.server.common.components.KotlinEnvironment
34
import model.ImportInfo
4-
import component.KotlinEnvironment
55
import org.jetbrains.kotlin.cli.jvm.compiler.CliBindingTrace
66
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
77
import org.jetbrains.kotlin.container.getService

0 commit comments

Comments
 (0)