Also added tests for kotlin
This commit is contained in:
cylee authored and GitHub committed 2025-08-23 14:27:16 +02:00
1 parent 80589726ec
commit 144e1357bd
10 files changed
+118 -6

No files matched your search

+5
View File
@@ -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
View File
@@ -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!")
}
}
+9
View File
@@ -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),
+52
View File
@@ -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"