Skip to content

Commit 19f0348

Browse files
authored
KTL-3015 implement Kotlin LSP proxy for completions (#878)
Implement lsp-based completions leveraging Kotlin-lsp through a WebFlux proxy capable of accepting POST requests and WebSocket requests.
1 parent ca7ff1b commit 19f0348

File tree

68 files changed

+3608
-540
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+3608
-540
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,5 @@ out/
3737

3838
### VS Code ###
3939
.vscode/
40+
41+
kotlin-lsp/

build.gradle.kts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ version = "${libs.versions.kotlin.get()}-SNAPSHOT"
1212
val propertyFile = "application.properties"
1313

1414
plugins {
15-
alias(libs.plugins.spring.boot)
16-
alias(libs.plugins.spring.dependency.management)
17-
alias(libs.plugins.kotlin.plugin.spring)
18-
id("base-kotlin-jvm-conventions")
15+
id("base-spring-boot-conventions")
1916
}
2017

2118
apply<NodeJsRootPlugin>()
@@ -40,7 +37,7 @@ dependencies {
4037
implementation("org.springframework.boot:spring-boot-starter-web")
4138
implementation("org.springframework.boot:spring-boot-starter-validation")
4239
implementation(libs.aws.springboot.container)
43-
implementation(libs.springdoc)
40+
implementation(libs.springdoc.webmvc)
4441
implementation(libs.gson)
4542
implementation(libs.kotlinx.serialization.json)
4643
implementation(libs.kotlin.compiler.arguments.description)
@@ -58,9 +55,6 @@ dependencies {
5855
implementation(project(":dependencies"))
5956

6057
testImplementation(libs.kotlin.test)
61-
testImplementation("org.springframework.boot:spring-boot-starter-test") {
62-
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
63-
}
6458
testImplementation(libs.kotlinx.coroutines.test)
6559

6660
resourceDependency(libs.skiko.js.wasm.runtime)
@@ -93,12 +87,6 @@ fun generateProperties(prefix: String = "") = """
9387
""".trimIndent()
9488

9589
tasks.withType<KotlinCompile> {
96-
compilerOptions {
97-
freeCompilerArgs.addAll(
98-
"-Xjsr305=strict",
99-
)
100-
101-
}
10290
dependsOn(":executors:jar")
10391
buildPropertyFile()
10492
}
@@ -146,7 +134,6 @@ tasks.withType<Test> {
146134
with(rootProject.kotlinNodeJsEnvSpec) {
147135
dependsOn(rootProject.nodeJsSetupTaskProvider)
148136
}
149-
useJUnitPlatform()
150137
javaLauncher.set(javaToolchains.launcherFor {
151138
languageVersion.set(JavaLanguageVersion.of(17))
152139
vendor.set(JvmVendorSpec.AMAZON)

buildSrc/settings.gradle.kts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,7 @@ pluginManagement {
22
includeBuild("../build-settings-logic")
33
}
44

5-
dependencyResolutionManagement {
6-
// For buildSrc we need to declare a custom path to the toml file with versions' catalog.
7-
// But for a root project we can't set `from` inside `versionCatalogs` catalog block for the default `libs` catalog.
8-
// (see https://github.com/gradle/gradle/issues/21328)
9-
// That is why it is not fully moved to the dependencyResolutionManagement block in the settings convention plugin.
10-
versionCatalogs {
11-
getByName("libs") {
12-
from(files("../gradle/libs.versions.toml"))
13-
}
14-
}
15-
}
16-
175
plugins {
186
id("kotlin-compiler-server-version-catalog")
7+
id("dev.panuszewski.typesafe-conventions") version "0.9.0"
198
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2+
3+
plugins {
4+
id("base-kotlin-jvm-conventions")
5+
6+
alias(libs.plugins.spring.boot)
7+
alias(libs.plugins.spring.dependency.management)
8+
alias(libs.plugins.kotlin.plugin.spring)
9+
}
10+
11+
dependencies {
12+
testImplementation(libs.spring.boot.starter.test) {
13+
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
14+
}
15+
}
16+
17+
tasks.withType<KotlinCompile>().configureEach {
18+
compilerOptions { freeCompilerArgs.addAll("-Xjsr305=strict") }
19+
}
20+
21+
tasks.withType<Test>().configureEach { useJUnitPlatform() }

common/src/main/kotlin/model/Completion.kt

Lines changed: 0 additions & 45 deletions
This file was deleted.

common/src/main/kotlin/model/Icon.kt

Lines changed: 0 additions & 16 deletions
This file was deleted.

completions/build.gradle.kts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import org.springframework.boot.gradle.tasks.bundling.BootBuildImage
2+
3+
plugins {
4+
id("base-spring-boot-conventions")
5+
}
6+
7+
version = "${libs.versions.kotlin.get()}-SNAPSHOT"
8+
9+
dependencies {
10+
implementation(libs.spring.boot.starter.webflux)
11+
implementation(libs.spring.boot.docker.compose)
12+
implementation(libs.springdoc.webflux)
13+
implementation(libs.org.eclipse.lsp4j)
14+
implementation(libs.kotlinx.coroutines.reactor)
15+
testImplementation(libs.kotlin.test)
16+
testImplementation(libs.bundles.testcontainers)
17+
testImplementation(libs.rector.test)
18+
}
19+
20+
tasks.named<BootBuildImage>("bootBuildImage") {
21+
// TODO(KTL-3803):push docker image to JB registry
22+
val baseImageName = "sfuri/kotlin-compiler-server-completions-lsp"
23+
// publish = true
24+
imageName = "$baseImageName:${project.version}"
25+
tags = setOf("$baseImageName:latest")
26+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/bash
2+
3+
export COMPLETIONS_SERVICE_PORT=8081
4+
5+
# export LSP_LOCAL_WORKSPACE_ROOT=lsp-users-projects-root
6+
export LSP_REMOTE_WORKSPACE_ROOT=lsp-users-projects-root-test
7+
8+
echo "building docker image for spring application"
9+
yes n | ../gradlew bootBuildImage
10+
11+
if [[ " $* " == *" --run "* ]]; then
12+
echo "requested starting completion service"
13+
docker compose up -d
14+
echo "completion service up and running"
15+
fi
16+
17+
exit 0

completions/compose.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
services:
2+
kotlin-lsp:
3+
image: sfuri/intellij-lsp
4+
ports:
5+
- "9999:9999"
6+
networks:
7+
- lsp-lsp-net
8+
9+
lsp-completions-service:
10+
image: sfuri/kotlin-compiler-server-completions-lsp
11+
ports:
12+
- "${COMPLETIONS_SERVICE_PORT}:8082"
13+
networks:
14+
- lsp-lsp-net
15+
environment:
16+
- LSP_HOST=kotlin-lsp
17+
- LSP_PORT=9999
18+
depends_on:
19+
- kotlin-lsp
20+
21+
networks:
22+
lsp-lsp-net:
23+
driver: bridge
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package completions
2+
3+
import completions.configuration.lsp.LspProperties
4+
import org.springframework.boot.autoconfigure.SpringBootApplication
5+
import org.springframework.boot.context.properties.EnableConfigurationProperties
6+
import org.springframework.boot.runApplication
7+
8+
@SpringBootApplication
9+
@EnableConfigurationProperties(value = [LspProperties::class])
10+
class CompletionsApplication
11+
12+
fun main(args: Array<String>) {
13+
runApplication<CompletionsApplication>(*args)
14+
}

0 commit comments

Comments
 (0)