mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-14 12:17:02 +00:00
Change kotlin lsp to official https://github.com/Kotlin/kotlin-lsp (#507)
Also added tests for kotlin
This commit is contained in:
1 parent
80589726ec
commit
144e1357bd
10 files changed
+118
-6
No files matched your search
@@ -65,6 +65,11 @@ jobs:
|
||||
uses: DeLaGuardo/setup-clojure@13.4
|
||||
with:
|
||||
cli: latest
|
||||
- name: Setup kotlin
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
- name: Install Terraform
|
||||
uses: hashicorp/setup-terraform@v3
|
||||
with:
|
||||
|
||||
+2
-1
@@ -254,6 +254,7 @@ markers = [
|
||||
"python: language server running for Python",
|
||||
"go: language server running for Go",
|
||||
"java: language server running for Java",
|
||||
"kotlin: language server running for kotlin",
|
||||
"rust: language server running for Rust",
|
||||
"typescript: language server running for TypeScript",
|
||||
"php: language server running for PHP",
|
||||
@@ -275,4 +276,4 @@ markers = [
|
||||
skip = '.git*,*.svg,*.lock,*.min.*'
|
||||
check-hidden = true
|
||||
# ignore-regex = ''
|
||||
# ignore-words-list = ''
|
||||
# ignore-words-list = ''
|
||||
@@ -43,7 +43,7 @@ class KotlinLanguageServer(SolidLanguageServer):
|
||||
self.runtime_dependency_paths = runtime_dependency_paths
|
||||
|
||||
# Create command to execute the Kotlin Language Server script
|
||||
cmd = f'"{self.runtime_dependency_paths.kotlin_executable_path}"'
|
||||
cmd = [self.runtime_dependency_paths.kotlin_executable_path, "--stdio"]
|
||||
|
||||
# Set environment variables including JAVA_HOME
|
||||
proc_env = {"JAVA_HOME": self.runtime_dependency_paths.java_home_path}
|
||||
@@ -76,7 +76,7 @@ class KotlinLanguageServer(SolidLanguageServer):
|
||||
"runtimeDependency": {
|
||||
"id": "KotlinLsp",
|
||||
"description": "Kotlin Language Server",
|
||||
"url": "https://github.com/fwcd/kotlin-language-server/releases/download/1.3.13/server.zip",
|
||||
"url": "https://download-cdn.jetbrains.com/kotlin-lsp/0.253.10629/kotlin-0.253.10629.zip",
|
||||
"archiveType": "zip",
|
||||
},
|
||||
"java": {
|
||||
@@ -138,13 +138,13 @@ class KotlinLanguageServer(SolidLanguageServer):
|
||||
assert os.path.exists(java_path), f"Java executable not found at {java_path}"
|
||||
|
||||
# Setup Kotlin Language Server paths
|
||||
kotlin_ls_dir = os.path.join(static_dir, "server")
|
||||
kotlin_ls_dir = static_dir
|
||||
|
||||
# Get platform-specific executable script path
|
||||
if platform_id.value.startswith("win-"):
|
||||
kotlin_script = os.path.join(kotlin_ls_dir, "bin", "kotlin-language-server.bat")
|
||||
kotlin_script = os.path.join(kotlin_ls_dir, "kotlin-lsp.cmd")
|
||||
else:
|
||||
kotlin_script = os.path.join(kotlin_ls_dir, "bin", "kotlin-language-server")
|
||||
kotlin_script = os.path.join(kotlin_ls_dir, "kotlin-lsp.sh")
|
||||
|
||||
# Download and extract Kotlin Language Server if script doesn't exist
|
||||
if not os.path.exists(kotlin_script):
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
plugins {
|
||||
kotlin("jvm") version "1.9.21"
|
||||
application
|
||||
}
|
||||
|
||||
group = "test.serena"
|
||||
version = "1.0-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package test_repo
|
||||
|
||||
object Main {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
Utils.printHello()
|
||||
val model = Model("Cascade")
|
||||
println(model.name)
|
||||
acceptModel(model)
|
||||
}
|
||||
|
||||
fun acceptModel(m: Model?) {
|
||||
// Do nothing, just for LSP reference
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package test_repo
|
||||
|
||||
data class Model(val name: String)
|
||||
@@ -0,0 +1,9 @@
|
||||
package test_repo
|
||||
|
||||
object ModelUser {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
val model = Model("Cascade")
|
||||
println(model.name)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test_repo
|
||||
|
||||
object Utils {
|
||||
fun printHello() {
|
||||
println("Hello from Utils!")
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ def serena_config():
|
||||
Language.PYTHON,
|
||||
Language.GO,
|
||||
Language.JAVA,
|
||||
Language.KOTLIN,
|
||||
Language.RUST,
|
||||
Language.TYPESCRIPT,
|
||||
Language.PHP,
|
||||
@@ -67,6 +68,7 @@ class TestSerenaAgent:
|
||||
pytest.param(Language.PYTHON, "User", "Class", "models.py", marks=pytest.mark.python),
|
||||
pytest.param(Language.GO, "Helper", "Function", "main.go", marks=pytest.mark.go),
|
||||
pytest.param(Language.JAVA, "Model", "Class", "Model.java", marks=pytest.mark.java),
|
||||
pytest.param(Language.KOTLIN, "Model", "Struct", "Model.kt", marks=pytest.mark.kotlin),
|
||||
pytest.param(Language.RUST, "add", "Function", "lib.rs", marks=pytest.mark.rust),
|
||||
pytest.param(Language.TYPESCRIPT, "DemoClass", "Class", "index.ts", marks=pytest.mark.typescript),
|
||||
pytest.param(Language.PHP, "helperFunction", "Function", "helper.php", marks=pytest.mark.php),
|
||||
@@ -110,6 +112,13 @@ class TestSerenaAgent:
|
||||
os.path.join("src", "main", "java", "test_repo", "Main.java"),
|
||||
marks=pytest.mark.java,
|
||||
),
|
||||
pytest.param(
|
||||
Language.KOTLIN,
|
||||
"Model",
|
||||
os.path.join("src", "main", "kotlin", "test_repo", "Model.kt"),
|
||||
os.path.join("src", "main", "kotlin", "test_repo", "Main.kt"),
|
||||
marks=pytest.mark.kotlin,
|
||||
),
|
||||
pytest.param(Language.RUST, "add", os.path.join("src", "lib.rs"), os.path.join("src", "main.rs"), marks=pytest.mark.rust),
|
||||
pytest.param(Language.TYPESCRIPT, "helperFunction", "index.ts", "use_helper.ts", marks=pytest.mark.typescript),
|
||||
pytest.param(Language.PHP, "helperFunction", "helper.php", "index.php", marks=pytest.mark.php),
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
from solidlsp import SolidLanguageServer
|
||||
from solidlsp.ls_config import Language
|
||||
from solidlsp.ls_utils import SymbolUtils
|
||||
|
||||
|
||||
@pytest.mark.kotlin
|
||||
class TestKotlinLanguageServer:
|
||||
@pytest.mark.parametrize("language_server", [Language.KOTLIN], indirect=True)
|
||||
def test_find_symbol(self, language_server: SolidLanguageServer) -> None:
|
||||
symbols = language_server.request_full_symbol_tree()
|
||||
assert SymbolUtils.symbol_tree_contains_name(symbols, "Main"), "Main class not found in symbol tree"
|
||||
assert SymbolUtils.symbol_tree_contains_name(symbols, "Utils"), "Utils class not found in symbol tree"
|
||||
assert SymbolUtils.symbol_tree_contains_name(symbols, "Model"), "Model class not found in symbol tree"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.KOTLIN], indirect=True)
|
||||
def test_find_referencing_symbols(self, language_server: SolidLanguageServer) -> None:
|
||||
# Use correct Kotlin file paths
|
||||
file_path = os.path.join("src", "main", "kotlin", "test_repo", "Utils.kt")
|
||||
refs = language_server.request_references(file_path, 3, 12)
|
||||
assert any("Main.kt" in ref.get("relativePath", "") for ref in refs), "Main should reference Utils.printHello"
|
||||
|
||||
# Dynamically determine the correct line/column for the 'Model' class name
|
||||
file_path = os.path.join("src", "main", "kotlin", "test_repo", "Model.kt")
|
||||
symbols = language_server.request_document_symbols(file_path)
|
||||
model_symbol = None
|
||||
for sym in symbols[0]:
|
||||
print(sym)
|
||||
print("\n")
|
||||
if sym.get("name") == "Model" and sym.get("kind") == 23: # 23 = Class
|
||||
model_symbol = sym
|
||||
break
|
||||
assert model_symbol is not None, "Could not find 'Model' class symbol in Model.kt"
|
||||
# Use selectionRange if present, otherwise fall back to range
|
||||
if "selectionRange" in model_symbol:
|
||||
sel_start = model_symbol["selectionRange"]["start"]
|
||||
else:
|
||||
sel_start = model_symbol["range"]["start"]
|
||||
refs = language_server.request_references(file_path, sel_start["line"], sel_start["character"])
|
||||
assert any(
|
||||
"Main.kt" in ref.get("relativePath", "") for ref in refs
|
||||
), "Main should reference Model (tried all positions in selectionRange)"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.KOTLIN], indirect=True)
|
||||
def test_overview_methods(self, language_server: SolidLanguageServer) -> None:
|
||||
symbols = language_server.request_full_symbol_tree()
|
||||
assert SymbolUtils.symbol_tree_contains_name(symbols, "Main"), "Main missing from overview"
|
||||
assert SymbolUtils.symbol_tree_contains_name(symbols, "Utils"), "Utils missing from overview"
|
||||
assert SymbolUtils.symbol_tree_contains_name(symbols, "Model"), "Model missing from overview"
|
||||
Reference in new issue
Block a user