├── LICENSE.txt ├── README.md ├── RELEASES.md ├── api.core ├── BUILD.bazel ├── language-server.api.core.iml ├── src │ └── com │ │ └── jetbrains │ │ └── ls │ │ └── api │ │ └── core │ │ ├── LSDocuments.kt │ │ ├── LSServer.kt │ │ ├── LSWorkspace.kt │ │ ├── util │ │ ├── LSUtil.kt │ │ ├── UriConverter.kt │ │ └── WorkspaceModelBuilder.kt │ │ └── workspace │ │ └── LSWorkspaceStructure.kt └── test │ └── com │ └── jetbrains │ └── ls │ └── api │ └── core │ └── util │ └── UriConverterTest.kt ├── api.features ├── BUILD.bazel ├── language-server.api.features.iml ├── resources │ └── META-INF │ │ └── language-server │ │ └── features │ │ └── api │ │ └── lsApi.xml ├── src │ └── com │ │ └── jetbrains │ │ └── ls │ │ └── api │ │ └── features │ │ ├── LSConfiguration.kt │ │ ├── LSConfigurationEntry.kt │ │ ├── codeActions │ │ ├── LSCodeActionProvider.kt │ │ ├── LSCodeActions.kt │ │ └── LSSimpleCodeActionProvider.kt │ │ ├── commands │ │ ├── LSCommand.kt │ │ ├── LSCommandDescriptor.kt │ │ ├── LSCommandDescriptorProvider.kt │ │ ├── LSCommandExecutor.kt │ │ └── document │ │ │ └── LSDocumentCommandComandExecutor.kt │ │ ├── completion │ │ ├── LSCompletion.kt │ │ ├── LSCompletionItemKindProvider.kt │ │ └── LSCompletionProvider.kt │ │ ├── configuration │ │ └── LSUniqueConfigurationEntry.kt │ │ ├── decompiler │ │ └── DecompilerResponse.kt │ │ ├── definition │ │ ├── LSDefinition.kt │ │ └── LSDefinitionProvider.kt │ │ ├── diagnostics │ │ ├── LSDiagnostic.kt │ │ └── LSDiagnosticProvider.kt │ │ ├── hover │ │ ├── LSHover.kt │ │ └── LSHoverProvider.kt │ │ ├── language │ │ ├── LSLanguage.kt │ │ └── LSLanguageConfiguration.kt │ │ ├── lsApiPlugin.kt │ │ ├── partialResults │ │ └── LSConcurrentResponseHandler.kt │ │ ├── references │ │ ├── LSReferences.kt │ │ └── LSReferencesProvider.kt │ │ ├── semanticTokens │ │ ├── LSSemanticTokenModifier.kt │ │ ├── LSSemanticTokenRegistry.kt │ │ ├── LSSemanticTokenType.kt │ │ ├── LSSemanticTokenWithRange.kt │ │ ├── LSSemanticTokens.kt │ │ ├── LSSemanticTokensProvider.kt │ │ └── encoding │ │ │ ├── SemanticTokensDecoder.kt │ │ │ └── SemanticTokensEncoder.kt │ │ ├── symbols │ │ ├── LSDocumentSymbolProvider.kt │ │ ├── LSDocumentSymbols.kt │ │ ├── LSWorkspaceSymbolProvider.kt │ │ └── LSWorkspaceSymbols.kt │ │ ├── textEdits │ │ ├── PsiFileTextEditsCollector.kt │ │ └── TextEditsComputer.kt │ │ └── utils │ │ ├── PsiSerializablePointer.kt │ │ └── ijPlugins.kt └── test │ ├── BUILD.bazel │ ├── language-server.api.features.test.iml │ └── test │ └── com │ └── jetbrains │ └── ls │ └── api │ └── features │ ├── semanticTokens │ └── SemanticTokensEncoderTest.kt │ └── textEdits │ └── TextEditsComputerTest.kt ├── features-impl ├── common │ ├── BUILD.bazel │ ├── language-server.api.features.impl.common.iml │ ├── resources │ │ └── META-INF │ │ │ └── language-server │ │ │ └── features │ │ │ └── common │ │ │ └── commonLsApi.xml │ └── src │ │ └── com │ │ └── jetbrains │ │ └── ls │ │ └── api │ │ └── features │ │ └── impl │ │ └── common │ │ ├── api │ │ └── commonLsApiPlugin.kt │ │ ├── completion │ │ └── LSCompletionProviderCommonImpl.kt │ │ ├── configuration │ │ └── LSCommonConfiguration.kt │ │ ├── decompiler │ │ └── LSDecompileCommandDescriptorProvider.kt │ │ ├── definitions │ │ └── LSDefinitionProviderCommonImpl.kt │ │ ├── diagnostics │ │ ├── DiagnosticData.kt │ │ ├── LSSyntaxErrorDiagnosticProviderImpl.kt │ │ └── inspections │ │ │ ├── InspectionDiagnosticData.kt │ │ │ ├── InspectionQuickfixData.kt │ │ │ ├── LSInspectionDiagnosticProviderImpl.kt │ │ │ └── LSInspectionFixesCodeActionProvider.kt │ │ ├── hover │ │ ├── LSHoverProviderCommonImpl.kt │ │ └── makrdownUtils.kt │ │ ├── references │ │ └── LSReferencesProviderCommonImpl.kt │ │ ├── symbols │ │ ├── AbstractLSDocumentSymbolProvider.kt │ │ └── AbstractLSWorkspaceSymbolProvider.kt │ │ ├── utils │ │ ├── editor.kt │ │ └── position.kt │ │ └── workspace │ │ └── LSExportWorkspaceCommandDescriptorProvider.kt └── kotlin │ ├── BUILD.bazel │ ├── language-server.api.features.impl.kotlin.iml │ ├── resources │ └── META-INF │ │ └── language-server │ │ └── features │ │ └── kotlin │ │ ├── codeActions.xml │ │ ├── completion.xml │ │ ├── lsApiKotlinImpl.xml │ │ └── usages.xml │ └── src │ └── com │ └── jetbrains │ └── ls │ └── api │ └── features │ └── impl │ └── common │ └── kotlin │ ├── apiImpl │ ├── lsApiKotlinImplPlugin.kt │ └── textEdits │ │ └── KotlinFileForModificationFactory.kt │ ├── codeActions │ ├── LSOrganizeImportsCodeActionProviderKotlinImpl.kt │ ├── NoOpReferenceShortener.kt │ └── kotlinCodeActionsPlugin.kt │ ├── codeStyle │ └── kotlinCodeStylePlugin.kt │ ├── completion │ ├── LSCompletionItemKindProviderKotlinImpl.kt │ ├── kotlinCompletionPlugin.kt │ └── rekot │ │ ├── CompletionItemFactory.kt │ │ ├── CompletionItemsCollector.kt │ │ ├── CompletionPopupFactory.kt │ │ ├── LSRekotBasedKotlinCompletionProviderImpl.kt │ │ ├── RekotCompletionItem.kt │ │ └── completionUtils.kt │ ├── configuration │ └── LSKotlinLanguageConfiguration.kt │ ├── definitions │ └── LSKotlinPackageDefinitionProvider.kt │ ├── diagnostics │ ├── compiler │ │ ├── KotlinCompilerDiagnosticData.kt │ │ ├── KotlinCompilerDiagnosticQuickfixData.kt │ │ ├── LSKotlinCompilerDiagnosticsFixesCodeActionProvider.kt │ │ ├── LSKotlinCompilerDiagnosticsProvider.kt │ │ └── kotlinCompilerDiagnosticUtils.kt │ └── intentions │ │ └── LSKotlinIntentionCodeActionProviderImpl.kt │ ├── hover │ ├── LSHoverProviderKotlinImpl.kt │ └── LSMarkdownDocProviderKotlinImpl.kt │ ├── language │ └── LSKotlinLanguage.kt │ ├── semanticTokens │ └── LSSemanticTokensProviderKotlinImpl.kt │ ├── symbols │ ├── LSDocumentSymbolProviderKotlin.kt │ ├── LSWorkspaceSymbolProviderKotlinImpl.kt │ └── kinds.kt │ └── usages │ └── kotlinUsagesIjPlugin.kt ├── images └── quickstart_sample.gif ├── kotlin-lsp ├── BUILD.bazel ├── README.md ├── language-server.kotlin-lsp.iml └── src │ └── com │ └── jetbrains │ └── ls │ └── kotlinLsp │ ├── KotlinLspServer.kt │ ├── connection │ └── Client.kt │ ├── logging │ └── logging.kt │ ├── requests │ ├── core │ │ ├── fileUpdates.kt │ │ ├── initialize.kt │ │ ├── shutdown.kt │ │ └── trace.kt │ └── features.kt │ └── util │ ├── librariesInitializer.kt │ └── systemInfo.kt ├── kotlin-vscode ├── .gitignore ├── .vscode │ └── launch.json ├── .vscodeignore ├── LICENSE ├── README.md ├── build.md ├── client │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── decompiler.ts │ │ ├── extension.ts │ │ ├── java.ts │ │ ├── lspClient.ts │ │ └── statusBar.ts │ ├── testSources │ │ └── tokenization │ │ │ ├── sample.kt │ │ │ └── sample.kt.snap │ └── tsconfig.json ├── icons │ └── kotlin.png ├── language-configuration.json ├── package-lock.json ├── package.json ├── syntaxes │ └── kotlin.tmLanguage.json └── tsconfig.json ├── scripts ├── kotlin-lsp.cmd ├── kotlin-lsp.sh ├── lsp-kotlin-emacs.el ├── neovim.md └── zed-settings.json └── workspace-import ├── BUILD.bazel ├── gen └── com │ └── jetbrains │ └── ls │ └── imports │ └── api │ └── impl │ └── MetadataStorageImpl.kt ├── language-server.project-import.iml ├── src └── com │ └── jetbrains │ └── ls │ └── imports │ ├── api │ ├── WorkspaceEntitySource.kt │ └── WorkspaceImporter.kt │ ├── gradle │ └── GradleWorkspaceImporter.kt │ ├── jps │ └── JpsWorkspaceImporter.kt │ ├── json │ ├── JsonWorkspaceImporter.kt │ ├── XmlUtils.kt │ ├── conversion.kt │ └── model.kt │ └── utils │ └── uri.kt └── test ├── BUILD.bazel ├── language-server.project-import.test.iml ├── test └── com │ └── jetbrains │ └── ls │ └── imports │ └── gradle │ └── ProjectImportTest.kt └── testData └── gradle ├── .gitignore ├── CustomSourceSets ├── app │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── .gitkeep │ │ ├── kotlin │ │ │ └── .gitkeep │ │ └── resources │ │ │ └── .gitkeep │ │ └── test │ │ ├── java │ │ └── .gitkeep │ │ ├── kotlin │ │ └── .gitkeep │ │ └── resources │ │ └── .gitkeep ├── build.gradle.kts ├── lib │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── .gitkeep │ │ ├── kotlin │ │ │ └── .gitkeep │ │ └── resources │ │ │ └── .gitkeep │ │ └── test │ │ ├── java │ │ └── .gitkeep │ │ ├── kotlin │ │ └── .gitkeep │ │ └── resources │ │ └── .gitkeep ├── settings.gradle.kts ├── src │ ├── main │ │ ├── java │ │ │ └── .gitkeep │ │ ├── kotlin │ │ │ └── .gitkeep │ │ └── resources │ │ │ └── .gitkeep │ └── test │ │ ├── java │ │ └── .gitkeep │ │ ├── kotlin │ │ └── .gitkeep │ │ └── resources │ │ └── .gitkeep └── workspace.json ├── Dependencies ├── build.gradle.kts ├── settings.gradle.kts ├── src │ ├── main │ │ ├── java │ │ │ └── .gitkeep │ │ ├── kotlin │ │ │ └── .gitkeep │ │ └── resources │ │ │ └── .gitkeep │ └── test │ │ ├── java │ │ └── .gitkeep │ │ ├── kotlin │ │ └── .gitkeep │ │ └── resources │ │ └── .gitkeep └── workspace.json ├── Empty └── .gitkeep ├── MultiProjectGroovyDSL ├── api │ ├── build.gradle │ └── src │ │ ├── main │ │ ├── java │ │ │ └── .gitkeep │ │ ├── kotlin │ │ │ └── .gitkeep │ │ └── resources │ │ │ └── .gitkeep │ │ └── test │ │ ├── java │ │ └── .gitkeep │ │ ├── kotlin │ │ └── .gitkeep │ │ └── resources │ │ └── .gitkeep ├── build.gradle ├── core │ ├── build.gradle │ └── src │ │ ├── main │ │ ├── java │ │ │ └── .gitkeep │ │ ├── kotlin │ │ │ └── .gitkeep │ │ └── resources │ │ │ └── .gitkeep │ │ └── test │ │ ├── java │ │ └── .gitkeep │ │ ├── kotlin │ │ └── .gitkeep │ │ └── resources │ │ └── .gitkeep ├── service │ ├── build.gradle │ └── src │ │ ├── main │ │ ├── java │ │ │ └── .gitkeep │ │ ├── kotlin │ │ │ └── .gitkeep │ │ └── resources │ │ │ └── .gitkeep │ │ └── test │ │ ├── java │ │ └── .gitkeep │ │ ├── kotlin │ │ └── .gitkeep │ │ └── resources │ │ └── .gitkeep ├── settings.gradle ├── src │ ├── main │ │ ├── java │ │ │ └── .gitkeep │ │ ├── kotlin │ │ │ └── .gitkeep │ │ └── resources │ │ │ └── .gitkeep │ └── test │ │ ├── java │ │ └── .gitkeep │ │ ├── kotlin │ │ └── .gitkeep │ │ └── resources │ │ └── .gitkeep └── workspace.json ├── MultiProjectKotlinDSL ├── api │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── .gitkeep │ │ ├── kotlin │ │ │ └── .gitkeep │ │ └── resources │ │ │ └── .gitkeep │ │ └── test │ │ ├── java │ │ └── .gitkeep │ │ ├── kotlin │ │ └── .gitkeep │ │ └── resources │ │ └── .gitkeep ├── build.gradle.kts ├── core │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── .gitkeep │ │ ├── kotlin │ │ │ └── .gitkeep │ │ └── resources │ │ │ └── .gitkeep │ │ └── test │ │ ├── java │ │ └── .gitkeep │ │ ├── kotlin │ │ └── .gitkeep │ │ └── resources │ │ └── .gitkeep ├── service │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ ├── java │ │ │ └── .gitkeep │ │ ├── kotlin │ │ │ └── .gitkeep │ │ └── resources │ │ │ └── .gitkeep │ │ └── test │ │ ├── java │ │ └── .gitkeep │ │ ├── kotlin │ │ └── .gitkeep │ │ └── resources │ │ └── .gitkeep ├── settings.gradle.kts ├── src │ ├── main │ │ ├── java │ │ │ └── .gitkeep │ │ ├── kotlin │ │ │ └── .gitkeep │ │ └── resources │ │ │ └── .gitkeep │ └── test │ │ ├── java │ │ └── .gitkeep │ │ ├── kotlin │ │ └── .gitkeep │ │ └── resources │ │ └── .gitkeep └── workspace.json ├── NonExistentDependency ├── build.gradle.kts ├── src │ ├── main │ │ ├── java │ │ │ └── .gitkeep │ │ ├── kotlin │ │ │ └── .gitkeep │ │ └── resources │ │ │ └── .gitkeep │ └── test │ │ ├── java │ │ └── .gitkeep │ │ ├── kotlin │ │ └── .gitkeep │ │ └── resources │ │ └── .gitkeep └── workspace.json └── PetClinic ├── build.gradle ├── src ├── main │ ├── java │ │ └── .gitkeep │ ├── kotlin │ │ └── .gitkeep │ └── resources │ │ └── .gitkeep └── test │ ├── java │ └── .gitkeep │ ├── kotlin │ └── .gitkeep │ └── resources │ └── .gitkeep └── workspace.json /api.core/BUILD.bazel: -------------------------------------------------------------------------------- 1 | ### auto-generated section `build language-server.api.core` start 2 | load("@community//build:compiler-options.bzl", "create_kotlinc_options") 3 | load("@rules_jvm//:jvm.bzl", "jvm_library", "jvm_test") 4 | 5 | create_kotlinc_options( 6 | name = "custom", 7 | context_receivers = True 8 | ) 9 | 10 | jvm_library( 11 | name = "api.core", 12 | module_name = "language-server.api.core", 13 | visibility = ["//visibility:public"], 14 | srcs = glob(["src/**/*.kt", "src/**/*.java"], allow_empty = True), 15 | kotlinc_opts = ":custom", 16 | deps = [ 17 | "@lib//:kotlin-stdlib", 18 | "@community//platform/core-api:core", 19 | "@community//platform/util", 20 | "@community//platform/workspace/storage", 21 | "@community//platform/workspace/jps", 22 | "@community//fleet/lsp.protocol", 23 | ] 24 | ) 25 | 26 | jvm_library( 27 | name = "api.core_test_lib", 28 | visibility = ["//visibility:public"], 29 | srcs = glob(["test/**/*.kt", "test/**/*.java"], allow_empty = True), 30 | kotlinc_opts = ":custom", 31 | associates = [":api.core"], 32 | deps = [ 33 | "@lib//:kotlin-stdlib", 34 | "@community//platform/core-api:core", 35 | "@community//platform/util", 36 | "@community//platform/workspace/storage", 37 | "@community//platform/workspace/jps", 38 | "@community//fleet/lsp.protocol", 39 | "@lib//:junit5", 40 | "@lib//:junit5Jupiter", 41 | ] 42 | ) 43 | 44 | jvm_test( 45 | name = "api.core_test", 46 | runtime_deps = [":api.core_test_lib"] 47 | ) 48 | ### auto-generated section `build language-server.api.core` end -------------------------------------------------------------------------------- /api.core/language-server.api.core.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /api.core/src/com/jetbrains/ls/api/core/LSDocuments.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.core 3 | 4 | import com.jetbrains.lsp.protocol.TextDocumentContentChangeEvent 5 | import com.jetbrains.lsp.protocol.URI 6 | 7 | interface LSDocuments { 8 | 9 | suspend fun didOpen(uri: URI, fileText: String, version: Long, languageId: String) 10 | 11 | suspend fun didClose(uri: URI) 12 | 13 | suspend fun didChange(uri: URI, changes: List) 14 | } 15 | -------------------------------------------------------------------------------- /api.core/src/com/jetbrains/ls/api/core/LSServer.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.core 3 | 4 | import com.intellij.openapi.project.Project 5 | import com.jetbrains.lsp.protocol.URI 6 | import kotlinx.coroutines.CoroutineScope 7 | 8 | interface LSServer { // workspace? 9 | /** 10 | * @param useSiteFileUri we may have multiple projects in the workspace, [URI] is used to find a correct one 11 | */ 12 | suspend fun withAnalysisContext( 13 | action: suspend context(LSAnalysisContext, CoroutineScope) () -> R, 14 | ): R 15 | 16 | suspend fun withWritableFile( 17 | useSiteFileUri: URI, 18 | action: suspend context(CoroutineScope) () -> R, 19 | ): R 20 | 21 | val documents: LSDocuments 22 | 23 | val workspaceStructure: LSWorkspaceStructure 24 | } 25 | 26 | interface LSAnalysisContext { 27 | val project: Project 28 | } 29 | 30 | interface LSServerStarter { 31 | suspend fun start(action: suspend context(LSServerContext, CoroutineScope) () -> Unit) 32 | } 33 | 34 | interface LSServerContext { 35 | suspend fun withServer(action: suspend context(LSServer, CoroutineScope) () -> Unit) 36 | } 37 | -------------------------------------------------------------------------------- /api.core/src/com/jetbrains/ls/api/core/LSWorkspace.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.core 3 | 4 | import com.intellij.platform.workspace.storage.ImmutableEntityStorage 5 | import com.intellij.platform.workspace.storage.MutableEntityStorage 6 | import com.intellij.platform.workspace.storage.url.VirtualFileUrlManager 7 | import kotlinx.coroutines.CoroutineScope 8 | import org.jetbrains.annotations.TestOnly 9 | 10 | interface LSWorkspaceStructure { 11 | 12 | suspend fun updateWorkspaceModelDirectly(updater: suspend CoroutineScope.(VirtualFileUrlManager, MutableEntityStorage) -> Unit) 13 | 14 | @TestOnly 15 | fun getEntityStorage(): ImmutableEntityStorage 16 | } 17 | 18 | -------------------------------------------------------------------------------- /api.core/src/com/jetbrains/ls/api/core/util/LSUtil.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.core.util 3 | 4 | import com.intellij.openapi.editor.Document 5 | import com.intellij.openapi.util.TextRange 6 | import com.intellij.openapi.vfs.VirtualFile 7 | import com.intellij.openapi.vfs.VirtualFileManager 8 | import com.jetbrains.lsp.protocol.* 9 | 10 | val VirtualFile.uri: URI 11 | get() = url.intellijUriToLspUri() 12 | 13 | fun Document.offsetByPosition(position: Position): Int = 14 | getLineStartOffset(position.line) + position.character 15 | 16 | fun Document.positionByOffset(offset: Int): Position { 17 | val line = getLineNumber(offset) 18 | return Position(line = line, character = offset - getLineStartOffset(line)) 19 | } 20 | 21 | fun URI.findVirtualFile(): VirtualFile? = 22 | lspUriToIntellijUri()?.let { VirtualFileManager.getInstance().findFileByUrl(it) } 23 | 24 | fun TextRange.toLspRange(document: Document): Range = 25 | Range( 26 | document.positionByOffset(startOffset), 27 | document.positionByOffset(endOffset), 28 | ) 29 | 30 | fun Range.toTextRange(document: Document): TextRange = 31 | TextRange( 32 | document.offsetByPosition(start), 33 | document.offsetByPosition(end), 34 | ) 35 | 36 | fun TextDocumentIdentifier.findVirtualFile(): VirtualFile? = uri.uri.findVirtualFile() 37 | 38 | fun DocumentUri.findVirtualFile(): VirtualFile? = uri.findVirtualFile() 39 | 40 | fun TextDocumentPositionParams.findVirtualFile(): VirtualFile? = textDocument.findVirtualFile() 41 | 42 | fun VirtualFile.isFromLibrary(): Boolean { 43 | val scheme = uri.scheme 44 | return scheme == "jrt" || scheme == "jar" || uri.uri.contains("!") 45 | } -------------------------------------------------------------------------------- /api.core/src/com/jetbrains/ls/api/core/workspace/LSWorkspaceStructure.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | -------------------------------------------------------------------------------- /api.features/BUILD.bazel: -------------------------------------------------------------------------------- 1 | ### auto-generated section `build language-server.api.features` start 2 | load("@community//build:compiler-options.bzl", "create_kotlinc_options") 3 | load("@rules_jvm//:jvm.bzl", "jvm_library", "jvm_resources") 4 | 5 | create_kotlinc_options( 6 | name = "custom", 7 | context_receivers = True, 8 | opt_in = ["org.jetbrains.kotlin.analysis.api.KaExperimentalApi"] 9 | ) 10 | 11 | jvm_resources( 12 | name = "api.features_resources", 13 | files = glob(["resources/**/*"]), 14 | strip_prefix = "resources" 15 | ) 16 | 17 | jvm_library( 18 | name = "api.features", 19 | module_name = "language-server.api.features", 20 | visibility = ["//visibility:public"], 21 | srcs = glob(["src/**/*.kt", "src/**/*.java"], allow_empty = True), 22 | kotlinc_opts = ":custom", 23 | deps = [ 24 | "@lib//:kotlin-stdlib", 25 | "@community//fleet/lsp.protocol", 26 | "@lib//:kotlinx-coroutines-core", 27 | "//language-server/community/api.core", 28 | "@community//platform/analysis-impl", 29 | "@community//platform/util", 30 | "@lib//:kotlinx-serialization-json", 31 | "@lib//:kotlinx-serialization-core", 32 | "@ultimate_lib//:java-diff-utils", 33 | ], 34 | runtime_deps = [":api.features_resources"] 35 | ) 36 | ### auto-generated section `build language-server.api.features` end -------------------------------------------------------------------------------- /api.features/language-server.api.features.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | $KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /api.features/resources/META-INF/language-server/features/api/lsApi.xml: -------------------------------------------------------------------------------- 1 | 2 | language-server/features/api 3 | JetBrains 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/LSConfigurationEntry.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features 3 | 4 | import com.jetbrains.ls.api.features.language.LSLanguage 5 | 6 | interface LSConfigurationEntry 7 | 8 | interface LSLanguageSpecificConfigurationEntry : LSConfigurationEntry { 9 | val supportedLanguages: Set 10 | } 11 | 12 | 13 | fun LSLanguageSpecificConfigurationEntry.supportLanguage(language: LSLanguage): Boolean = 14 | supportedLanguages.contains(language) -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/codeActions/LSCodeActionProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.codeActions 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSLanguageSpecificConfigurationEntry 6 | import com.jetbrains.lsp.protocol.CodeAction 7 | import com.jetbrains.lsp.protocol.CodeActionParams 8 | import kotlinx.coroutines.flow.Flow 9 | 10 | interface LSCodeActionProvider : LSLanguageSpecificConfigurationEntry { 11 | context(LSServer) 12 | fun getCodeActions(params: CodeActionParams): Flow 13 | } 14 | -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/codeActions/LSCodeActions.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.codeActions 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.ls.api.features.partialResults.LSConcurrentResponseHandler 7 | import com.jetbrains.lsp.implementation.LspHandlerContext 8 | import com.jetbrains.lsp.protocol.CodeAction 9 | import com.jetbrains.lsp.protocol.CodeActionParams 10 | 11 | object LSCodeActions { 12 | context(LSServer, LSConfiguration, LspHandlerContext) 13 | suspend fun getCodeActions(params: CodeActionParams): List { 14 | return LSConcurrentResponseHandler.streamResultsIfPossibleOrRespondDirectly( 15 | params.partialResultToken, 16 | CodeAction.serializer(), 17 | entriesFor(params.textDocument), 18 | ) { 19 | it.getCodeActions(params) 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/commands/LSCommand.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.commands 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.lsp.implementation.LspHandlerContext 7 | import com.jetbrains.lsp.implementation.throwLspError 8 | import com.jetbrains.lsp.protocol.Commands.ExecuteCommand 9 | import com.jetbrains.lsp.protocol.ErrorCodes 10 | import com.jetbrains.lsp.protocol.ExecuteCommandParams 11 | import kotlinx.serialization.json.JsonElement 12 | 13 | object LSCommand { 14 | context(LSServer, LspHandlerContext, LSConfiguration) 15 | suspend fun executeCommand(params: ExecuteCommandParams): JsonElement { 16 | val descriptor = commandDescriptorByCommandName(params.command) 17 | ?: throwLspError(ExecuteCommand, "Unknown command: ${params.command}", Unit, ErrorCodes.InvalidRequest, null) 18 | return descriptor.executor.execute(params.arguments ?: emptyList()) 19 | } 20 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/commands/LSCommandDescriptor.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.commands 3 | 4 | class LSCommandDescriptor( 5 | val title: String, 6 | val name: String, 7 | val executor: LSCommandExecutor 8 | ) -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/commands/LSCommandDescriptorProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.commands 3 | 4 | import com.jetbrains.ls.api.features.LSConfigurationEntry 5 | 6 | interface LSCommandDescriptorProvider : LSConfigurationEntry { 7 | val commandDescriptors: List 8 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/commands/LSCommandExecutor.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.commands 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.lsp.implementation.LspHandlerContext 6 | import kotlinx.serialization.json.JsonElement 7 | 8 | fun interface LSCommandExecutor { 9 | context(LspHandlerContext, LSServer) 10 | suspend fun execute(arguments: List): JsonElement 11 | } 12 | -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/commands/document/LSDocumentCommandComandExecutor.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.commands.document 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.commands.LSCommandExecutor 6 | import com.jetbrains.lsp.implementation.LspHandlerContext 7 | import com.jetbrains.lsp.protocol.* 8 | import kotlinx.serialization.json.JsonElement 9 | import kotlinx.serialization.json.JsonPrimitive 10 | import kotlinx.serialization.json.decodeFromJsonElement 11 | 12 | fun interface LSDocumentCommandExecutor : LSCommandExecutor { 13 | context(LspHandlerContext, LSServer) 14 | suspend fun executeForDocument(documentUri: DocumentUri, otherArgs: List): List 15 | 16 | context(LspHandlerContext, LSServer) 17 | override suspend fun execute(arguments: List): JsonElement { 18 | require(arguments.isNotEmpty()) { "Expected >= 1 argument, got: ${arguments.size}" } 19 | val documentUri = LSP.json.decodeFromJsonElement(arguments.first()) 20 | 21 | val edits = executeForDocument(documentUri, arguments.drop(1)) 22 | if (edits.isNotEmpty()) { 23 | // todo handle returned results 24 | lspClient.request( 25 | ApplyEditRequests.ApplyEdit, 26 | ApplyWorkspaceEditParams( 27 | label = null, 28 | edit = WorkspaceEdit( 29 | changes = mapOf(documentUri to edits) 30 | ) 31 | ) 32 | ) 33 | } 34 | // TODO we just need to return smth, not sure that the result is used 35 | return JsonPrimitive(true) 36 | } 37 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/completion/LSCompletion.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.completion 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.ls.api.features.utils.PsiSerializablePointer 7 | import com.jetbrains.lsp.protocol.* 8 | import kotlinx.serialization.Serializable 9 | import kotlinx.serialization.json.decodeFromJsonElement 10 | 11 | object LSCompletion { 12 | context(LSServer, LSConfiguration) 13 | suspend fun getCompletion(params: CompletionParams): CompletionList { 14 | // todo support partial results 15 | val results = entriesFor(params.textDocument).map { it.provideCompletion(params) } 16 | return results.combined() 17 | } 18 | 19 | context(LSServer, LSConfiguration) 20 | suspend fun resolveCompletion(params: CompletionItem): CompletionItem { 21 | val data: CompletionItemData = runCatching { 22 | val data = params.data ?: return params 23 | LSP.json.decodeFromJsonElement(data) 24 | }.getOrNull() ?: return params 25 | return entries().firstOrNull { it.uniqueId == data.providerId }?.resolveCompletion(params) ?: params 26 | } 27 | 28 | private fun List.combined(): CompletionList { 29 | if (isEmpty()) return CompletionList.EMPTY_COMPLETE 30 | if (size == 1) return first() 31 | 32 | require(all { it.isIncomplete }) { "Combining incomplete results is not yet supported" } 33 | require(all { it.itemDefaults == null }) { "Combining itemDefaults is not yet supported" } 34 | return CompletionList( 35 | isIncomplete = false, 36 | items = flatMap { it.items } 37 | ) 38 | } 39 | } 40 | 41 | //todo should be later moved to a common features module 42 | @Serializable 43 | data class CompletionItemData( 44 | val providerId: String, 45 | val params: CompletionParams, 46 | val lookupString: String, 47 | val pointer: PsiSerializablePointer? 48 | ) 49 | -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/completion/LSCompletionItemKindProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.completion 3 | 4 | import com.intellij.lang.Language 5 | import com.intellij.lang.LanguageExtension 6 | import com.intellij.psi.PsiElement 7 | import com.jetbrains.lsp.protocol.CompletionItemKind 8 | 9 | interface LSCompletionItemKindProvider { 10 | fun getKind(element: PsiElement): CompletionItemKind? 11 | 12 | private object Extension : LanguageExtension("ls.completionItemKindProvider") 13 | 14 | companion object { 15 | fun getKind(element: PsiElement): CompletionItemKind? = 16 | forLanguage(element.language)?.getKind(element) ?: forLanguage(Language.ANY)?.getKind(element) 17 | 18 | fun forLanguage(language: Language): LSCompletionItemKindProvider? = 19 | Extension.forLanguage(language) 20 | } 21 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/completion/LSCompletionProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.completion 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSLanguageSpecificConfigurationEntry 6 | import com.jetbrains.ls.api.features.configuration.LSUniqueConfigurationEntry 7 | import com.jetbrains.lsp.protocol.CompletionItem 8 | import com.jetbrains.lsp.protocol.CompletionList 9 | import com.jetbrains.lsp.protocol.CompletionParams 10 | 11 | interface LSCompletionProvider : LSLanguageSpecificConfigurationEntry, LSUniqueConfigurationEntry { 12 | val supportsResolveRequest: Boolean 13 | 14 | context(LSServer) 15 | suspend fun provideCompletion(params: CompletionParams): CompletionList 16 | 17 | context(LSServer) 18 | suspend fun resolveCompletion(completionItem: CompletionItem): CompletionItem? = null 19 | } 20 | -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/configuration/LSUniqueConfigurationEntry.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.configuration 3 | 4 | interface LSUniqueConfigurationEntry { 5 | val uniqueId: String 6 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/decompiler/DecompilerResponse.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.decompiler 3 | 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class DecompilerResponse(val code: String, val language: String) -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/definition/LSDefinition.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.definition 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.ls.api.features.partialResults.LSConcurrentResponseHandler 7 | import com.jetbrains.lsp.implementation.LspHandlerContext 8 | import com.jetbrains.lsp.protocol.DefinitionParams 9 | import com.jetbrains.lsp.protocol.Location 10 | 11 | object LSDefinition { 12 | context(LSServer, LSConfiguration, LspHandlerContext) 13 | suspend fun getDefinition(params: DefinitionParams): List { 14 | return LSConcurrentResponseHandler.streamResultsIfPossibleOrRespondDirectly( 15 | params.partialResultToken, 16 | Location.serializer(), 17 | entriesFor(params.textDocument), 18 | ) { 19 | it.provideDefinitions(params) 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/definition/LSDefinitionProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.definition 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSLanguageSpecificConfigurationEntry 6 | import com.jetbrains.lsp.protocol.DefinitionParams 7 | import com.jetbrains.lsp.protocol.Location 8 | import kotlinx.coroutines.flow.Flow 9 | 10 | interface LSDefinitionProvider : LSLanguageSpecificConfigurationEntry { 11 | context(LSServer) 12 | fun provideDefinitions(params: DefinitionParams): Flow 13 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/diagnostics/LSDiagnostic.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.diagnostics 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.ls.api.features.partialResults.LSConcurrentResponseHandler 7 | import com.jetbrains.lsp.implementation.LspHandlerContext 8 | import com.jetbrains.lsp.protocol.DocumentDiagnosticParams 9 | import com.jetbrains.lsp.protocol.DocumentDiagnosticReport 10 | import com.jetbrains.lsp.protocol.DocumentDiagnosticReportKind 11 | 12 | object LSDiagnostic { 13 | context(LSServer, LSConfiguration, LspHandlerContext) 14 | suspend fun getDiagnostics(params: DocumentDiagnosticParams): DocumentDiagnosticReport { 15 | // partial results in diagnotics, according to the LSP spec (https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#documentDiagnosticReportPartialResult), 16 | // support only partial results for related diagnostics, not for the diagnostics for the current document, 17 | // so we just collect results concurrently from all handlers 18 | val diagnostics = LSConcurrentResponseHandler.respondDirectlyWithResultsCollectedConcurrently( 19 | entriesFor(params.textDocument), 20 | ) { it.getDiagnostics(params) } 21 | return DocumentDiagnosticReport( 22 | DocumentDiagnosticReportKind.Full, 23 | resultId = null, 24 | items = diagnostics, 25 | relatedDocuments = null, 26 | ) 27 | } 28 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/diagnostics/LSDiagnosticProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.diagnostics 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSLanguageSpecificConfigurationEntry 6 | import com.jetbrains.lsp.protocol.Diagnostic 7 | import com.jetbrains.lsp.protocol.DocumentDiagnosticParams 8 | import kotlinx.coroutines.flow.Flow 9 | 10 | interface LSDiagnosticProvider : LSLanguageSpecificConfigurationEntry { 11 | // todo handle other parts of `DocumentDiagnosticReport` 12 | context(LSServer) 13 | fun getDiagnostics(params: DocumentDiagnosticParams): Flow 14 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/hover/LSHover.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.hover 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.lsp.protocol.Hover 7 | import com.jetbrains.lsp.protocol.HoverParams 8 | 9 | object LSHover { 10 | context(LSConfiguration, LSServer) 11 | suspend fun getHover(params: HoverParams): Hover? { 12 | return entriesFor(params.textDocument).firstNotNullOfOrNull { it.getHover(params) } 13 | } 14 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/hover/LSHoverProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.hover 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.ls.api.features.LSLanguageSpecificConfigurationEntry 7 | import com.jetbrains.lsp.protocol.Hover 8 | import com.jetbrains.lsp.protocol.HoverParams 9 | 10 | interface LSHoverProvider : LSLanguageSpecificConfigurationEntry { 11 | context(LSServer) 12 | suspend fun getHover(params: HoverParams): Hover? 13 | } 14 | 15 | -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/language/LSLanguage.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.language 3 | 4 | import com.intellij.lang.Language 5 | import com.jetbrains.lsp.protocol.DocumentUri 6 | import com.jetbrains.lsp.protocol.TextDocumentIdentifier 7 | import com.jetbrains.lsp.protocol.URI 8 | 9 | class LSLanguage( 10 | /** 11 | * Should be unique 12 | */ 13 | val lspName: String, 14 | val intellijLanguage: Language, 15 | extensions: Collection, 16 | ) { 17 | val extensions: Set = extensions.map { it.removePrefix(".") }.toSet() 18 | 19 | override fun toString(): String = lspName 20 | override fun equals(other: Any?): Boolean = other is LSLanguage && other.lspName == lspName 21 | override fun hashCode(): Int = lspName.hashCode() 22 | } 23 | 24 | fun LSLanguage.matches(uri: TextDocumentIdentifier): Boolean { 25 | return matches(uri.uri) 26 | } 27 | 28 | fun LSLanguage.matches(uri: DocumentUri): Boolean { 29 | return matches(uri.uri) 30 | } 31 | 32 | fun LSLanguage.matches(uri: URI): Boolean { 33 | return uri.fileExtension in extensions 34 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/language/LSLanguageConfiguration.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.language 3 | 4 | import com.intellij.ide.plugins.PluginMainDescriptor 5 | import com.jetbrains.ls.api.features.LSConfigurationEntry 6 | 7 | class LSLanguageConfiguration( 8 | val entries: List, 9 | val plugins: List, 10 | val languages: List, 11 | ) -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/lsApiPlugin.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features 3 | 4 | import com.intellij.ide.plugins.PluginMainDescriptor 5 | import com.jetbrains.ls.api.features.utils.ijPluginByXml 6 | 7 | val lsApiPlugin: PluginMainDescriptor = ijPluginByXml("META-INF/language-server/features/api/lsApi.xml") -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/partialResults/LSConcurrentResponseHandler.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.partialResults 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.lsp.implementation.LspHandlerContext 6 | import com.jetbrains.lsp.implementation.streamResultsIfPossibleOrRespondDirectly 7 | import com.jetbrains.lsp.protocol.ProgressToken 8 | import kotlinx.coroutines.ExperimentalCoroutinesApi 9 | import kotlinx.coroutines.flow.Flow 10 | import kotlinx.coroutines.flow.asFlow 11 | import kotlinx.coroutines.flow.flattenMerge 12 | import kotlinx.coroutines.flow.toList 13 | import kotlinx.serialization.KSerializer 14 | 15 | internal object LSConcurrentResponseHandler { 16 | context(LspHandlerContext, LSServer) 17 | suspend fun respondDirectlyWithResultsCollectedConcurrently( 18 | providers: List, 19 | getResults: (H) -> Flow 20 | ): List { 21 | if (providers.isEmpty()) return emptyList() 22 | return providers.map { getResults(it) }.concurrentMerge().toList() 23 | } 24 | 25 | 26 | context(LspHandlerContext, LSServer) 27 | suspend fun streamResultsIfPossibleOrRespondDirectly( 28 | partialResultToken: ProgressToken?, 29 | resultSerializer: KSerializer, 30 | providers: List, 31 | getResults: (H) -> Flow 32 | ): List { 33 | if (providers.isEmpty()) return emptyList() 34 | return providers 35 | .map { getResults(it) } 36 | .concurrentMerge() 37 | .streamResultsIfPossibleOrRespondDirectly(lspClient, partialResultToken, resultSerializer) 38 | 39 | } 40 | 41 | @OptIn(ExperimentalCoroutinesApi::class) 42 | private fun List>.concurrentMerge(): Flow = asFlow().flattenMerge() 43 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/references/LSReferences.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.references 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.ls.api.features.partialResults.LSConcurrentResponseHandler 7 | import com.jetbrains.lsp.implementation.LspHandlerContext 8 | import com.jetbrains.lsp.protocol.Location 9 | import com.jetbrains.lsp.protocol.ReferenceParams 10 | 11 | object LSReferences { 12 | context(LSServer, LSConfiguration, LspHandlerContext) 13 | suspend fun getReferences(params: ReferenceParams): List { 14 | return LSConcurrentResponseHandler.streamResultsIfPossibleOrRespondDirectly( 15 | params.partialResultToken, 16 | Location.serializer(), 17 | entriesFor(params.textDocument), 18 | ) { 19 | it.getReferences(params) 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/references/LSReferencesProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.references 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSLanguageSpecificConfigurationEntry 6 | import com.jetbrains.lsp.protocol.Location 7 | import com.jetbrains.lsp.protocol.ReferenceParams 8 | import kotlinx.coroutines.flow.Flow 9 | 10 | interface LSReferencesProvider : LSLanguageSpecificConfigurationEntry { 11 | context(LSServer) 12 | fun getReferences(params: ReferenceParams): Flow 13 | } 14 | -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/semanticTokens/LSSemanticTokenModifier.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.semanticTokens 3 | 4 | interface LSSemanticTokenModifier { 5 | val name: String 6 | } 7 | 8 | class LSSemanticTokenModifierCustom( 9 | override val name: String 10 | ) : LSSemanticTokenModifier { 11 | override fun toString(): String = name 12 | override fun equals(other: Any?): Boolean = this === other || other is LSSemanticTokenModifier && other.name == name 13 | override fun hashCode(): Int = name.hashCode() 14 | } 15 | 16 | class LSSemanticTokenModifierPredefined private constructor( 17 | override val name: String 18 | ) : LSSemanticTokenModifier { 19 | override fun toString(): String = name 20 | override fun equals(other: Any?): Boolean = this === other || other is LSSemanticTokenModifier && other.name == name 21 | override fun hashCode(): Int = name.hashCode() 22 | 23 | companion object { 24 | private val all: MutableList = mutableListOf() 25 | 26 | private fun predefined(name: String): LSSemanticTokenModifierPredefined { 27 | val token = LSSemanticTokenModifierPredefined(name) 28 | all.add(token) 29 | return token 30 | } 31 | 32 | /** For declarations of symbols. */ 33 | val DECLARATION: LSSemanticTokenModifierPredefined = predefined("declaration") 34 | 35 | /** For definitions of symbols, for example, in header files. */ 36 | val DEFINITION: LSSemanticTokenModifierPredefined = predefined("definition") 37 | 38 | /** For readonly variables and member fields (constants). */ 39 | val READONLY: LSSemanticTokenModifierPredefined = predefined("readonly") 40 | 41 | /** For class members (static members). */ 42 | val STATIC: LSSemanticTokenModifierPredefined = predefined("static") 43 | 44 | /** For symbols that should no longer be used. */ 45 | val DEPRECATED: LSSemanticTokenModifierPredefined = predefined("deprecated") 46 | 47 | /** For types and member functions that are abstract. */ 48 | val ABSTRACT: LSSemanticTokenModifierPredefined = predefined("abstract") 49 | 50 | /** For functions that are marked async. */ 51 | val ASYNC: LSSemanticTokenModifierPredefined = predefined("async") 52 | 53 | /** For variable references where the variable is assigned to. */ 54 | val MODIFICATION: LSSemanticTokenModifierPredefined = predefined("modification") 55 | 56 | /** For occurrences of symbols in documentation. */ 57 | val DOCUMENTATION: LSSemanticTokenModifierPredefined = predefined("documentation") 58 | 59 | /** For symbols that are part of the standard library. */ 60 | val DEFAULT_LIBRARY: LSSemanticTokenModifierPredefined = predefined("defaultLibrary") 61 | 62 | val ALL: List = all.toList() 63 | 64 | init { 65 | all.clear() 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/semanticTokens/LSSemanticTokenRegistry.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.semanticTokens 3 | 4 | class LSSemanticTokenRegistry( 5 | val types: List, 6 | val modifiers: List, 7 | ) { 8 | 9 | init { 10 | requireUnique(types) 11 | requireUnique(modifiers) 12 | } 13 | 14 | private fun requireUnique(list: List) { 15 | val set = mutableSetOf() 16 | for (element in list) { 17 | require(!set.contains(element)) { 18 | "Duplicate value $element in list: $list" 19 | } 20 | set.add(element) 21 | } 22 | } 23 | 24 | private val typeToIndex: Map = 25 | types.withIndex().associate { it.value to it.index } 26 | 27 | private val modifierToIndex: Map = 28 | modifiers.withIndex().associate { it.value to it.index } 29 | 30 | fun typeToIndex(type: LSSemanticTokenType): Int { 31 | return typeToIndex[type] 32 | ?: error("Unregistered semantic token type: $type") 33 | } 34 | 35 | fun indexToType(index: Int): LSSemanticTokenType { 36 | return types[index] 37 | } 38 | 39 | fun modifierToIndex(modifier: LSSemanticTokenModifier): Int { 40 | return modifierToIndex[modifier] 41 | ?: error("Unregistered semantic token modifier: $modifier") 42 | } 43 | 44 | fun indexToModifier(index: Int): LSSemanticTokenModifier { 45 | return modifiers[index] 46 | } 47 | 48 | companion object { 49 | val EMPTY: LSSemanticTokenRegistry = LSSemanticTokenRegistry( 50 | types = emptyList(), 51 | modifiers = emptyList(), 52 | ) 53 | } 54 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/semanticTokens/LSSemanticTokenWithRange.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.semanticTokens 3 | 4 | import com.jetbrains.lsp.protocol.Range 5 | import java.util.* 6 | 7 | class LSSemanticTokenWithRange( 8 | val token: LSSemanticToken, 9 | val range: Range, 10 | ) { 11 | override fun toString(): String = "LSRangeWithSemanticToken($token, $range)" 12 | 13 | override fun equals(other: Any?): Boolean = 14 | this === other || 15 | other is LSSemanticTokenWithRange 16 | && other.range == range 17 | && other.token == token 18 | 19 | override fun hashCode(): Int = Objects.hash(range, token) 20 | } 21 | 22 | class LSSemanticToken( 23 | val type: LSSemanticTokenType, 24 | val modifiers: List = emptyList(), 25 | ) { 26 | fun withModifiers(vararg modifiers: LSSemanticTokenModifier): LSSemanticToken = 27 | LSSemanticToken(type, this.modifiers + modifiers) 28 | 29 | override fun toString(): String = "LSSemanticToken($type, $modifiers)" 30 | 31 | override fun equals(other: Any?): Boolean = 32 | this === other || 33 | other is LSSemanticToken 34 | && other.type == type 35 | && other.modifiers == modifiers 36 | 37 | override fun hashCode(): Int = Objects.hash(type) 38 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/semanticTokens/LSSemanticTokens.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.semanticTokens 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.ls.api.features.semanticTokens.encoding.SemanticTokensEncoder 7 | import com.jetbrains.lsp.protocol.SemanticTokens 8 | import com.jetbrains.lsp.protocol.SemanticTokensParams 9 | 10 | object LSSemanticTokens { 11 | context(LSServer, LSConfiguration) 12 | suspend fun semanticTokensFull(params: SemanticTokensParams): SemanticTokens { 13 | // todo send partial results here 14 | val providers = entriesFor(params.textDocument) 15 | val result = providers.flatMap { it.full(params) } 16 | val registry = createRegistry() 17 | val encoded = SemanticTokensEncoder.encode(result, registry) 18 | return SemanticTokens(resultId = null, data = encoded) 19 | } 20 | 21 | context(LSConfiguration) 22 | fun createRegistry(): LSSemanticTokenRegistry { 23 | val registries = entries().map { it.createRegistry() } 24 | if (registries.isEmpty()) return LSSemanticTokenRegistry.EMPTY 25 | if (registries.size == 1) return registries.first() 26 | return LSSemanticTokenRegistry( 27 | registries.flatMap { it.types }.distinct(), 28 | registries.flatMap { it.modifiers }.distinct(), 29 | ) 30 | } 31 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/semanticTokens/LSSemanticTokensProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.semanticTokens 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfigurationEntry 6 | import com.jetbrains.ls.api.features.LSLanguageSpecificConfigurationEntry 7 | import com.jetbrains.lsp.protocol.SemanticTokensParams 8 | 9 | interface LSSemanticTokensProvider : LSLanguageSpecificConfigurationEntry { 10 | fun createRegistry(): LSSemanticTokenRegistry 11 | 12 | /** 13 | * LSP method `textDocument/semanticTokens/full` 14 | */ 15 | context(LSServer) 16 | suspend fun full(params: SemanticTokensParams): List 17 | } 18 | -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/symbols/LSDocumentSymbolProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.symbols 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSLanguageSpecificConfigurationEntry 6 | import com.jetbrains.lsp.protocol.DocumentSymbol 7 | import com.jetbrains.lsp.protocol.DocumentSymbolParams 8 | import kotlinx.coroutines.flow.Flow 9 | 10 | interface LSDocumentSymbolProvider : LSLanguageSpecificConfigurationEntry { 11 | context(LSServer) 12 | fun getDocumentSymbols(params: DocumentSymbolParams): Flow 13 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/symbols/LSDocumentSymbols.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.symbols 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.ls.api.features.partialResults.LSConcurrentResponseHandler 7 | import com.jetbrains.lsp.implementation.LspHandlerContext 8 | import com.jetbrains.lsp.protocol.DocumentSymbol 9 | import com.jetbrains.lsp.protocol.DocumentSymbolParams 10 | 11 | object LSDocumentSymbols { 12 | context(LSServer, LSConfiguration, LspHandlerContext) 13 | suspend fun getSymbols(params: DocumentSymbolParams): List = 14 | LSConcurrentResponseHandler.streamResultsIfPossibleOrRespondDirectly( 15 | params.partialResultToken, 16 | DocumentSymbol.serializer(), 17 | entriesFor(params.textDocument), 18 | ) { 19 | it.getDocumentSymbols(params) 20 | } 21 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/symbols/LSWorkspaceSymbolProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.symbols 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfigurationEntry 6 | import com.jetbrains.lsp.protocol.WorkspaceSymbol 7 | import com.jetbrains.lsp.protocol.WorkspaceSymbolParams 8 | import kotlinx.coroutines.flow.Flow 9 | 10 | interface LSWorkspaceSymbolProvider : LSConfigurationEntry { 11 | context(LSServer) 12 | fun getWorkspaceSymbols(params: WorkspaceSymbolParams): Flow 13 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/symbols/LSWorkspaceSymbols.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.symbols 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.ls.api.features.partialResults.LSConcurrentResponseHandler 7 | import com.jetbrains.lsp.implementation.LspHandlerContext 8 | import com.jetbrains.lsp.protocol.WorkspaceSymbol 9 | import com.jetbrains.lsp.protocol.WorkspaceSymbolParams 10 | 11 | object LSWorkspaceSymbols { 12 | context(LSServer, LSConfiguration, LspHandlerContext) 13 | suspend fun getSymbols(params: WorkspaceSymbolParams): List { 14 | return LSConcurrentResponseHandler.streamResultsIfPossibleOrRespondDirectly( 15 | params.partialResultToken, 16 | WorkspaceSymbol.serializer(), 17 | entries(), 18 | ) { 19 | it.getWorkspaceSymbols(params) 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/utils/PsiSerializablePointer.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.utils 3 | 4 | import com.intellij.openapi.vfs.VirtualFile 5 | import com.intellij.psi.PsiElement 6 | import com.intellij.psi.PsiFile 7 | import com.intellij.psi.PsiFileSystemItem 8 | import com.intellij.psi.util.endOffset 9 | import com.intellij.psi.util.startOffset 10 | import com.jetbrains.ls.api.core.util.uri 11 | import com.jetbrains.ls.api.core.LSAnalysisContext 12 | import com.jetbrains.ls.api.core.LSServer 13 | import com.jetbrains.lsp.protocol.URI 14 | import kotlinx.serialization.Serializable 15 | 16 | @Serializable 17 | sealed class PsiSerializablePointer { 18 | internal abstract val uri: URI 19 | internal abstract val elementClass: String 20 | 21 | abstract fun restore(psiFile: PsiFile): PsiElement? 22 | 23 | abstract fun matches(element: PsiElement): Boolean 24 | 25 | @Serializable 26 | internal data class PsiFileSerializablePointer( 27 | override val uri: URI, 28 | override val elementClass: String, 29 | ) : PsiSerializablePointer() { 30 | 31 | override fun restore(psiFile: PsiFile): PsiElement? { 32 | return psiFile 33 | } 34 | 35 | override fun matches(element: PsiElement): Boolean { 36 | return element::class.java.name == elementClass 37 | } 38 | } 39 | 40 | @Serializable 41 | internal data class PsiElementSerializablePointer( 42 | override val uri: URI, 43 | override val elementClass: String, 44 | val startOffset: Int, 45 | val endOffset: Int, 46 | ) : PsiSerializablePointer() { 47 | override fun restore(psiFile: PsiFile): PsiElement? { 48 | var candidate: PsiElement? = psiFile.findElementAt(startOffset) ?: return null 49 | while (candidate != null && candidate !is PsiFileSystemItem) { 50 | if (matches(candidate)) { 51 | return candidate 52 | } 53 | candidate = candidate.parent 54 | } 55 | return null 56 | } 57 | 58 | override fun matches(element: PsiElement): Boolean { 59 | return element::class.java.name == elementClass 60 | && element.startOffset == startOffset 61 | && element.endOffset == endOffset 62 | } 63 | } 64 | 65 | companion object { 66 | context(LSAnalysisContext, LSServer) 67 | fun create(psi: PsiElement, file: VirtualFile): PsiSerializablePointer { 68 | return when (psi) { 69 | is PsiFile -> { 70 | PsiFileSerializablePointer(file.uri, psi::class.java.name) 71 | } 72 | 73 | else -> PsiElementSerializablePointer( 74 | uri = file.uri, 75 | elementClass = psi::class.java.name, 76 | startOffset = psi.textRange.startOffset, 77 | endOffset = psi.textRange.endOffset, 78 | ) 79 | } 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /api.features/src/com/jetbrains/ls/api/features/utils/ijPlugins.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.utils 3 | 4 | import com.intellij.ide.plugins.PluginMainDescriptor 5 | import com.intellij.ide.plugins.PluginManagerCore 6 | import com.intellij.ide.plugins.loadAndInitForCoreEnv 7 | import com.intellij.openapi.application.PathManager 8 | import com.intellij.openapi.extensions.PluginId 9 | import java.nio.file.Path 10 | import java.nio.file.Paths 11 | 12 | 13 | fun ijPluginByXml( 14 | xmlResourcePath: String, 15 | classForClasspath: Class<*>, 16 | useFakePluginId: Boolean = false, 17 | ): PluginMainDescriptor { 18 | val xmlResourcePath = xmlResourcePath.removePrefix("/") 19 | val pluginRoot = getPluginRoot(classForClasspath) 20 | fun createFakePluginId(): PluginId = PluginId.getId(xmlResourcePath) 21 | 22 | return when { 23 | xmlResourcePath.startsWith(PluginManagerCore.META_INF) -> { 24 | // normal plugin xml 25 | loadAndInitForCoreEnv( 26 | pluginRoot, 27 | xmlResourcePath, relativeDir = "", 28 | id = if (useFakePluginId) createFakePluginId() else null 29 | ) 30 | } 31 | 32 | else -> { 33 | // v2 plugin xml 34 | loadAndInitForCoreEnv(pluginRoot, xmlResourcePath, relativeDir = "", id = createFakePluginId()) 35 | } 36 | } 37 | ?: error("Failed to load plugin descriptor from $xmlResourcePath") 38 | } 39 | 40 | private fun getPluginRoot(classForClasspath: Class<*>): Path { 41 | val path = "/" + classForClasspath.name.replace('.', '/') + ".class" 42 | val resourceRoot = PathManager.getResourceRoot(classForClasspath, path) 43 | ?: error("Resource not found: $path") 44 | return Paths.get(resourceRoot) 45 | } 46 | 47 | /** 48 | * Takes a classpath of the current file facade (current file module) 49 | * 50 | * The function is inline to have a correct classloader of the call-side 51 | */ 52 | @Suppress("NOTHING_TO_INLINE") 53 | inline fun ijPluginByXml(xmlResourcePath: String): PluginMainDescriptor { 54 | return ijPluginByXml(xmlResourcePath, object : Any() {}::class.java) 55 | } -------------------------------------------------------------------------------- /api.features/test/BUILD.bazel: -------------------------------------------------------------------------------- 1 | ### auto-generated section `build language-server.api.features.test` start 2 | load("@rules_java//java:defs.bzl", "java_library") 3 | load("@rules_jvm//:jvm.bzl", "jvm_library", "jvm_test") 4 | 5 | java_library( 6 | name = "test", 7 | visibility = ["//visibility:public"] 8 | ) 9 | 10 | jvm_library( 11 | name = "test_test_lib", 12 | visibility = ["//visibility:public"], 13 | srcs = glob(["test/**/*.kt", "test/**/*.java"], allow_empty = True), 14 | deps = [ 15 | "@lib//:kotlin-stdlib", 16 | "@community//fleet/lsp.protocol", 17 | "@lib//:kotlinx-coroutines-core", 18 | "//language-server/community/api.core", 19 | "//language-server/community/api.core:api.core_test_lib", 20 | "@community//platform/analysis-impl", 21 | "@community//platform/util", 22 | "@lib//:kotlinx-serialization-json", 23 | "@lib//:kotlinx-serialization-core", 24 | "@ultimate_lib//:java-diff-utils", 25 | "@lib//:junit5", 26 | "@lib//:junit5Jupiter", 27 | "//language-server/test-api:test-api_test_lib", 28 | "//language-server/community/api.features", 29 | ] 30 | ) 31 | 32 | jvm_test( 33 | name = "test_test", 34 | runtime_deps = [":test_test_lib"] 35 | ) 36 | ### auto-generated section `build language-server.api.features.test` end -------------------------------------------------------------------------------- /api.features/test/language-server.api.features.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /features-impl/common/BUILD.bazel: -------------------------------------------------------------------------------- 1 | ### auto-generated section `build language-server.api.features.impl.common` start 2 | load("@community//build:compiler-options.bzl", "create_kotlinc_options") 3 | load("@rules_jvm//:jvm.bzl", "jvm_library", "jvm_resources") 4 | 5 | create_kotlinc_options( 6 | name = "custom", 7 | context_receivers = True, 8 | opt_in = ["org.jetbrains.kotlin.analysis.api.KaExperimentalApi"] 9 | ) 10 | 11 | jvm_resources( 12 | name = "common_resources", 13 | files = glob(["resources/**/*"]), 14 | strip_prefix = "resources" 15 | ) 16 | 17 | jvm_library( 18 | name = "common", 19 | module_name = "language-server.api.features.impl.common", 20 | visibility = ["//visibility:public"], 21 | srcs = glob(["src/**/*.kt", "src/**/*.java"], allow_empty = True), 22 | kotlinc_opts = ":custom", 23 | deps = [ 24 | "@lib//:kotlin-stdlib", 25 | "@lib//:kotlinx-coroutines-core", 26 | "@community//platform/analysis-api:analysis", 27 | "@community//platform/workspace/storage", 28 | "//language-server/community/api.core", 29 | "@community//platform/analysis-impl", 30 | "@community//platform/util", 31 | "//language-server/community/api.features", 32 | "@community//platform/util:util-ui", 33 | "@community//platform/editor-ui-api:editor-ui", 34 | "@community//platform/editor-ui-ex:editor-ex", 35 | "@lib//:kotlinx-serialization-json", 36 | "@lib//:kotlinx-serialization-core", 37 | "//language-server/analyzer", 38 | "@community//fleet/lsp.protocol", 39 | "@community//platform/code-style-api:codeStyle", 40 | "@community//platform/lang-impl", 41 | "@community//java/java-psi-api:psi", 42 | "@community//platform/indexing-api:indexing", 43 | "@community//platform/core-ui", 44 | "//codeServer/core", 45 | "//language-server/community/workspace-import:language-server-project-import", 46 | ], 47 | runtime_deps = [":common_resources"] 48 | ) 49 | ### auto-generated section `build language-server.api.features.impl.common` end -------------------------------------------------------------------------------- /features-impl/common/language-server.api.features.impl.common.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | $KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /features-impl/common/resources/META-INF/language-server/features/common/commonLsApi.xml: -------------------------------------------------------------------------------- 1 | 2 | language-server/common/api/ 3 | JetBrains 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/api/commonLsApiPlugin.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.api 3 | 4 | import com.intellij.ide.plugins.PluginMainDescriptor 5 | import com.jetbrains.ls.api.features.utils.ijPluginByXml 6 | 7 | internal val commonLsApiPlugin: PluginMainDescriptor = 8 | ijPluginByXml("META-INF/language-server/features/common/commonLsApi.xml") -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/configuration/LSCommonConfiguration.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.configuration 3 | 4 | import com.jetbrains.ls.api.features.impl.common.api.commonLsApiPlugin 5 | import com.jetbrains.ls.api.features.impl.common.decompiler.LSDecompileCommandDescriptorProvider 6 | import com.jetbrains.ls.api.features.impl.common.workspace.LSExportWorkspaceCommandDescriptorProvider 7 | import com.jetbrains.ls.api.features.language.LSLanguageConfiguration 8 | import com.jetbrains.ls.api.features.lsApiPlugin 9 | 10 | val LSCommonConfiguration: LSLanguageConfiguration = LSLanguageConfiguration( 11 | entries = listOf( 12 | LSDecompileCommandDescriptorProvider, 13 | LSExportWorkspaceCommandDescriptorProvider, 14 | ), 15 | plugins = listOf( 16 | lsApiPlugin, 17 | commonLsApiPlugin, 18 | ), 19 | languages = emptyList(), 20 | ) -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/decompiler/LSDecompileCommandDescriptorProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.decompiler 3 | 4 | import com.intellij.openapi.application.runReadAction 5 | import com.intellij.openapi.vfs.findPsiFile 6 | import com.jetbrains.ls.api.core.util.findVirtualFile 7 | import com.jetbrains.ls.api.features.commands.LSCommandDescriptor 8 | import com.jetbrains.ls.api.features.commands.LSCommandDescriptorProvider 9 | import com.jetbrains.ls.api.features.decompiler.DecompilerResponse 10 | import com.jetbrains.lsp.implementation.throwLspError 11 | import com.jetbrains.lsp.protocol.Commands.ExecuteCommand 12 | import com.jetbrains.lsp.protocol.DocumentUri 13 | import com.jetbrains.lsp.protocol.ErrorCodes 14 | import com.jetbrains.lsp.protocol.LSP 15 | import kotlinx.serialization.json.JsonPrimitive 16 | import kotlinx.serialization.json.decodeFromJsonElement 17 | import kotlinx.serialization.json.encodeToJsonElement 18 | 19 | object LSDecompileCommandDescriptorProvider : LSCommandDescriptorProvider { 20 | private val ALLOWED_SCHEMES = setOf("jar", "jrt") 21 | 22 | override val commandDescriptors: List = 23 | listOf(LSCommandDescriptor("Decompile", "decompile",) { arguments -> 24 | if (arguments.size != 1) { 25 | throwLspError(ExecuteCommand, "Expected 1 argument, got: ${arguments.size}", Unit, ErrorCodes.InvalidParams, null) 26 | } 27 | val documentUri = LSP.json.decodeFromJsonElement(arguments.first()) 28 | val scheme = documentUri.uri.scheme 29 | if (scheme !in ALLOWED_SCHEMES) { 30 | throwLspError(ExecuteCommand, "Unexpected URI scheme to decompile: $scheme", Unit, ErrorCodes.InvalidParams, null) 31 | } 32 | val response: DecompilerResponse? = withAnalysisContext { 33 | runReadAction { 34 | val psiFile = documentUri.findVirtualFile()?.findPsiFile(project) 35 | psiFile?.let { DecompilerResponse(it.text, it.language.id.lowercase()) } 36 | } 37 | } 38 | 39 | response?.let{LSP.json.encodeToJsonElement(it)} ?: JsonPrimitive(null as String?) 40 | } 41 | ) 42 | } -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/diagnostics/DiagnosticData.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.diagnostics 3 | 4 | import com.jetbrains.lsp.protocol.CodeActionParams 5 | import com.jetbrains.lsp.protocol.Diagnostic 6 | import com.jetbrains.lsp.protocol.LSP 7 | import kotlinx.serialization.Serializable 8 | import kotlinx.serialization.json.decodeFromJsonElement 9 | 10 | interface DiagnosticData { 11 | val diagnosticSource: DiagnosticSource 12 | } 13 | 14 | @Serializable 15 | data class DiagnosticSource( 16 | val name: String, 17 | ) 18 | 19 | inline fun Diagnostic.diagnosticData(): D? { 20 | val data = data ?: return null 21 | return runCatching { 22 | LSP.json.decodeFromJsonElement(data) 23 | }.getOrNull() 24 | } 25 | 26 | inline fun CodeActionParams.diagnosticData(): List> { 27 | return context.diagnostics.mapNotNull { diagnostic -> 28 | val data = diagnostic.diagnosticData() ?: return@mapNotNull null 29 | DiagnosticWithData(diagnostic, data) 30 | } 31 | } 32 | 33 | class DiagnosticWithData( 34 | val diagnostic: Diagnostic, 35 | val data: D, 36 | ) -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/diagnostics/LSSyntaxErrorDiagnosticProviderImpl.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.diagnostics 3 | 4 | import com.intellij.openapi.application.runReadAction 5 | import com.intellij.openapi.editor.Document 6 | import com.intellij.openapi.vfs.findDocument 7 | import com.intellij.openapi.vfs.findPsiFile 8 | import com.intellij.psi.PsiErrorElement 9 | import com.intellij.psi.PsiFile 10 | import com.intellij.psi.util.descendantsOfType 11 | import com.jetbrains.ls.api.core.LSServer 12 | import com.jetbrains.ls.api.core.util.findVirtualFile 13 | import com.jetbrains.ls.api.core.util.toLspRange 14 | import com.jetbrains.ls.api.features.diagnostics.LSDiagnosticProvider 15 | import com.jetbrains.ls.api.features.language.LSLanguage 16 | import com.jetbrains.lsp.protocol.Diagnostic 17 | import com.jetbrains.lsp.protocol.DiagnosticSeverity 18 | import com.jetbrains.lsp.protocol.DocumentDiagnosticParams 19 | import com.jetbrains.lsp.protocol.StringOrInt 20 | import kotlinx.coroutines.flow.Flow 21 | import kotlinx.coroutines.flow.flow 22 | 23 | class LSSyntaxErrorDiagnosticProviderImpl( 24 | override val supportedLanguages: Set, 25 | ) : LSDiagnosticProvider { 26 | context(LSServer) 27 | override fun getDiagnostics(params: DocumentDiagnosticParams): Flow = flow { 28 | withAnalysisContext { 29 | runReadAction a@ { 30 | val file = params.textDocument.findVirtualFile() ?: return@a emptyList() 31 | val document = file.findDocument() ?: return@a emptyList() 32 | val psiFile = file.findPsiFile(project) ?: return@a emptyList() 33 | getSyntaxErrors(psiFile, document) 34 | } 35 | }.forEach { emit(it) } 36 | } 37 | 38 | private fun getSyntaxErrors(psiFile: PsiFile, document: Document): List { 39 | val diagnostics = mutableListOf() 40 | for (errorElement in psiFile.descendantsOfType()) { 41 | diagnostics += Diagnostic( 42 | errorElement.textRange.toLspRange(document), 43 | severity = DiagnosticSeverity.Error, 44 | code = StringOrInt.string("SYNTAX"), 45 | message = errorElement.errorDescription, 46 | ) 47 | } 48 | return diagnostics 49 | } 50 | } -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/diagnostics/inspections/InspectionDiagnosticData.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.diagnostics.inspections 3 | 4 | import com.jetbrains.ls.api.features.impl.common.diagnostics.DiagnosticData 5 | import com.jetbrains.ls.api.features.impl.common.diagnostics.DiagnosticSource 6 | import kotlinx.serialization.Serializable 7 | 8 | @Serializable 9 | internal data class InspectionDiagnosticData( 10 | val fixes: List, 11 | ) : DiagnosticData { 12 | override val diagnosticSource: DiagnosticSource = source 13 | 14 | companion object { 15 | val source: DiagnosticSource = DiagnosticSource("inspection") 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/diagnostics/inspections/InspectionQuickfixData.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.diagnostics.inspections 3 | 4 | import com.intellij.codeInspection.LocalInspectionTool 5 | import com.intellij.codeInspection.QuickFix 6 | import com.intellij.openapi.vfs.VirtualFile 7 | import com.intellij.psi.PsiElement 8 | import com.jetbrains.ls.api.core.LSAnalysisContext 9 | import com.jetbrains.ls.api.core.LSServer 10 | import com.jetbrains.ls.api.features.utils.PsiSerializablePointer 11 | import kotlinx.serialization.Serializable 12 | 13 | @Serializable 14 | internal data class InspectionQuickfixData( 15 | val inspectionClass: String, 16 | /** 17 | * An element on which the [LocalInspectionTool] took as a root to report a quickfix. 18 | * It may or may not be the element on which the quickfix was really reported 19 | */ 20 | val basePsiElement: PsiSerializablePointer, 21 | val name: String, 22 | val familyName: String, 23 | val fixClass: String, 24 | ) { 25 | fun matches(fix: QuickFix<*>): Boolean { 26 | return fixClass == fix::class.java.name 27 | && name == fix.name 28 | && familyName == fix.familyName 29 | } 30 | 31 | companion object { 32 | context(LSAnalysisContext, LSServer) 33 | fun createByFix( 34 | fix: QuickFix<*>, 35 | inspectionTool: LocalInspectionTool, 36 | basePsiElement: PsiElement, 37 | file: VirtualFile, 38 | ): InspectionQuickfixData { 39 | return InspectionQuickfixData( 40 | inspectionClass = inspectionTool::class.java.name, 41 | basePsiElement = PsiSerializablePointer.create(basePsiElement, file), 42 | name = fix.name, 43 | familyName = fix.familyName, 44 | fixClass = fix::class.java.name, 45 | ) 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/hover/LSHoverProviderCommonImpl.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.hover 3 | 4 | import com.intellij.lang.Language 5 | import com.intellij.lang.LanguageExtension 6 | import com.intellij.openapi.application.runReadAction 7 | import com.intellij.openapi.vfs.VirtualFile 8 | import com.intellij.openapi.vfs.findDocument 9 | import com.intellij.openapi.vfs.findPsiFile 10 | import com.intellij.psi.PsiElement 11 | import com.intellij.psi.PsiReference 12 | import com.jetbrains.ls.api.core.util.findVirtualFile 13 | import com.jetbrains.ls.api.core.util.offsetByPosition 14 | import com.jetbrains.ls.api.core.util.toLspRange 15 | import com.jetbrains.ls.api.core.LSAnalysisContext 16 | import com.jetbrains.ls.api.core.LSServer 17 | import com.jetbrains.ls.api.features.hover.LSHoverProvider 18 | import com.jetbrains.lsp.protocol.Hover 19 | import com.jetbrains.lsp.protocol.HoverParams 20 | import com.jetbrains.lsp.protocol.MarkupContent 21 | import com.jetbrains.lsp.protocol.MarkupKindType 22 | 23 | abstract class AbstractLSHoverProvider : LSHoverProvider { 24 | context(LSServer) 25 | override suspend fun getHover(params: HoverParams): Hover? { 26 | return withAnalysisContext { 27 | runReadAction a@{ 28 | val file = params.findVirtualFile() ?: return@a null 29 | val psiFile = file.findPsiFile(project) ?: return@a null 30 | val document = file.findDocument() ?: return@a null 31 | val offset = document.offsetByPosition(params.position) 32 | val reference = psiFile.findReferenceAt(offset) ?: return@a null 33 | 34 | val markdown = generateMarkdownForElementReferencedBy(file, reference) ?: return@a null 35 | 36 | Hover( 37 | MarkupContent(MarkupKindType.Markdown, markdown), 38 | range = reference.element.textRange.toLspRange(document), 39 | ) 40 | } 41 | } 42 | } 43 | 44 | context(LSServer, LSAnalysisContext) 45 | abstract fun generateMarkdownForElementReferencedBy(virtualFile: VirtualFile, reference: PsiReference): String? 46 | 47 | interface LSMarkdownDocProvider { 48 | fun getMarkdownDoc(element: PsiElement): String? 49 | 50 | private object Extension : LanguageExtension("ls.markdownDocProvider") 51 | 52 | companion object { 53 | fun getMarkdownDoc(element: PsiElement): String? = 54 | forLanguage(element.language)?.getMarkdownDoc(element) 55 | 56 | fun forLanguage(language: Language): LSMarkdownDocProvider? = 57 | Extension.forLanguage(language) 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/hover/makrdownUtils.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.hover 3 | 4 | fun markdownMultilineCode(code: String, language: String?): String { 5 | return buildString { 6 | // quadruple quotes to be able to have backticks inside the code 7 | appendLine("````${language.orEmpty()}") 8 | appendLine(code) 9 | appendLine("````") 10 | } 11 | } -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/references/LSReferencesProviderCommonImpl.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.references 3 | 4 | import com.intellij.find.findUsages.FindUsagesManager 5 | import com.intellij.model.psi.PsiSymbolService 6 | import com.intellij.model.psi.impl.targetSymbols 7 | import com.intellij.openapi.application.runReadAction 8 | import com.intellij.openapi.progress.runBlockingCancellable 9 | import com.intellij.openapi.vfs.findDocument 10 | import com.intellij.openapi.vfs.findPsiFile 11 | import com.jetbrains.ls.api.core.LSServer 12 | import com.jetbrains.ls.api.core.util.findVirtualFile 13 | import com.jetbrains.ls.api.core.util.offsetByPosition 14 | import com.jetbrains.ls.api.features.impl.common.utils.getLspLocationForDefinition 15 | import com.jetbrains.ls.api.features.language.LSLanguage 16 | import com.jetbrains.ls.api.features.references.LSReferencesProvider 17 | import com.jetbrains.lsp.protocol.Location 18 | import com.jetbrains.lsp.protocol.ReferenceParams 19 | import kotlinx.coroutines.flow.Flow 20 | import kotlinx.coroutines.flow.channelFlow 21 | 22 | class LSReferencesProviderCommonImpl( 23 | override val supportedLanguages: Set, 24 | ) : LSReferencesProvider { 25 | context(LSServer) 26 | override fun getReferences(params: ReferenceParams): Flow = channelFlow { 27 | withAnalysisContext { 28 | runReadAction a@{ 29 | val file = params.findVirtualFile() ?: return@a 30 | val psiFile = file.findPsiFile(project) ?: return@a 31 | val document = file.findDocument() ?: return@a 32 | val offset = document.offsetByPosition(params.position) 33 | val psiSymbolService = PsiSymbolService.getInstance() 34 | val targets = targetSymbols(psiFile, offset).mapNotNull { psiSymbolService.extractElementFromSymbol(it) } 35 | if (targets.isEmpty()) return@a 36 | 37 | val findUsagesManager = FindUsagesManager(project) 38 | val target = targets.first()/*todo handle all of them?*/ 39 | val handler = findUsagesManager.getFindUsagesHandler(target, true/*forbid showing dialogs*/) ?: return@a 40 | 41 | if (params.context.includeDeclaration) { 42 | target.getLspLocationForDefinition()?.let { 43 | runBlockingCancellable { 44 | channel.send(it) 45 | } 46 | } 47 | } 48 | handler.processElementUsages( 49 | target, { result -> 50 | val location = result.element?.getLspLocationForDefinition() ?: return@processElementUsages true 51 | 52 | runBlockingCancellable { 53 | channel.send(location) 54 | } 55 | true 56 | }, 57 | handler.findUsagesOptions 58 | ) 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/symbols/AbstractLSDocumentSymbolProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.symbols 3 | 4 | import com.intellij.openapi.application.runReadAction 5 | import com.intellij.openapi.vfs.findPsiFile 6 | import com.intellij.psi.PsiElement 7 | import com.intellij.psi.PsiNameIdentifierOwner 8 | import com.jetbrains.ls.api.core.LSAnalysisContext 9 | import com.jetbrains.ls.api.core.LSServer 10 | import com.jetbrains.ls.api.core.util.findVirtualFile 11 | import com.jetbrains.ls.api.features.impl.common.utils.getLspLocation 12 | import com.jetbrains.ls.api.features.impl.common.utils.getLspLocationForDefinition 13 | import com.jetbrains.ls.api.features.symbols.LSDocumentSymbolProvider 14 | import com.jetbrains.lsp.protocol.DocumentSymbol 15 | import com.jetbrains.lsp.protocol.DocumentSymbolParams 16 | import com.jetbrains.lsp.protocol.SymbolKind 17 | import com.jetbrains.lsp.protocol.SymbolTag 18 | import kotlinx.coroutines.flow.Flow 19 | import kotlinx.coroutines.flow.emitAll 20 | import kotlinx.coroutines.flow.flow 21 | 22 | abstract class AbstractLSDocumentSymbolProvider : LSDocumentSymbolProvider { 23 | context(LSServer) 24 | override fun getDocumentSymbols(params: DocumentSymbolParams): Flow = flow { 25 | val uri = params.textDocument.uri.uri 26 | withAnalysisContext { 27 | runReadAction { 28 | uri.findVirtualFile() 29 | ?.findPsiFile(project) 30 | ?.let { getNestedDeclarations(it) } 31 | ?.mapNotNull { declaration -> 32 | mapDeclaration(declaration) 33 | } ?: emptyList() 34 | } 35 | }.forEach { emit(it) } 36 | } 37 | 38 | context(LSAnalysisContext) 39 | private fun mapDeclaration(element: PsiElement): DocumentSymbol? { 40 | val name = getName(element) ?: return null 41 | val kind = getKind(element) ?: return null 42 | val range = element.getLspLocation()?.range ?: return null 43 | val selectionRange = element.getLspLocationForDefinition()?.range ?: return null 44 | val deprecated = isDeprecated(element) 45 | return DocumentSymbol( 46 | name = name, 47 | detail = null, // TODO: calculate signatures 48 | kind = kind, 49 | tags = if (deprecated) listOf(SymbolTag.Deprecated) else null, 50 | deprecated = deprecated, 51 | range = range, 52 | selectionRange = selectionRange, 53 | children = getNestedDeclarations(element).mapNotNull { mapDeclaration(it) }.takeIf { it.isNotEmpty() } 54 | ) 55 | } 56 | 57 | protected open fun getName(element: PsiElement): String? = 58 | when (element) { 59 | is PsiNameIdentifierOwner -> element.name 60 | else -> null 61 | } 62 | 63 | protected abstract fun getKind(element: PsiElement): SymbolKind? 64 | protected abstract fun isDeprecated(element: PsiElement): Boolean 65 | protected abstract fun getNestedDeclarations(element: PsiElement): List 66 | } -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/symbols/AbstractLSWorkspaceSymbolProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.symbols 3 | 4 | import com.intellij.navigation.ChooseByNameContributor 5 | import com.intellij.navigation.NavigationItem 6 | import com.intellij.openapi.application.runReadAction 7 | import com.jetbrains.ls.api.core.LSAnalysisContext 8 | import com.jetbrains.ls.api.core.LSServer 9 | import com.jetbrains.ls.api.features.symbols.LSWorkspaceSymbolProvider 10 | import com.jetbrains.lsp.protocol.WorkspaceSymbol 11 | import com.jetbrains.lsp.protocol.WorkspaceSymbolParams 12 | import kotlinx.coroutines.channels.SendChannel 13 | import kotlinx.coroutines.coroutineScope 14 | import kotlinx.coroutines.flow.Flow 15 | import kotlinx.coroutines.flow.channelFlow 16 | import kotlinx.coroutines.launch 17 | 18 | abstract class AbstractLSWorkspaceSymbolProvider : LSWorkspaceSymbolProvider { 19 | abstract fun getContributors(): List 20 | 21 | context(LSServer, LSAnalysisContext) 22 | abstract fun createWorkspaceSymbol(item: NavigationItem, contributor: ChooseByNameContributor): WorkspaceSymbol? 23 | 24 | context(LSServer) 25 | final override fun getWorkspaceSymbols(params: WorkspaceSymbolParams): Flow = channelFlow { 26 | withAnalysisContext { 27 | coroutineScope { 28 | for (contributor in getContributors()) { 29 | launch { handleContributor(contributor, params.query, channel) } 30 | } 31 | } 32 | } 33 | } 34 | 35 | context(LSServer, LSAnalysisContext) 36 | private suspend fun handleContributor( 37 | contributor: ChooseByNameContributor, 38 | query: String, 39 | channel: SendChannel 40 | ) { 41 | val names = runReadAction { contributor.getNames(project, /* includeNonProjectItems = */ false) } 42 | if (names.isEmpty()) return 43 | for (name in names) { 44 | if (query.isEmpty() || name.contains(query, ignoreCase = true)/*TODO some fancy fuzzy search should probably be here*/) { 45 | val items = runReadAction { contributor.getItemsByName(name, query, project, /* includeNonProjectItems = */ false) } 46 | for (item in items) { 47 | runReadAction { createWorkspaceSymbol(item, contributor) }?.let { channel.send(it) } 48 | } 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/utils/editor.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.utils 3 | 4 | import com.intellij.openapi.editor.Document 5 | import com.intellij.openapi.editor.impl.ImaginaryEditor 6 | import com.jetbrains.ls.api.core.LSAnalysisContext 7 | 8 | context(LSAnalysisContext) 9 | fun createEditorWithCaret(document: Document, caretOffset: Int): ImaginaryEditor { 10 | val editor = ImaginaryEditor(project, document) 11 | editor.caretModel.primaryCaret.moveToOffset(caretOffset) 12 | return editor 13 | } -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/utils/position.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.utils 3 | 4 | import com.intellij.openapi.editor.Document 5 | import com.intellij.openapi.util.TextRange 6 | import com.intellij.openapi.vfs.VirtualFile 7 | import com.intellij.openapi.vfs.findDocument 8 | import com.intellij.psi.PsiElement 9 | import com.intellij.psi.PsiNameIdentifierOwner 10 | import com.jetbrains.ls.api.core.util.toLspRange 11 | import com.jetbrains.ls.api.core.util.uri 12 | import com.jetbrains.ls.api.core.LSAnalysisContext 13 | import com.jetbrains.lsp.protocol.DocumentUri 14 | import com.jetbrains.lsp.protocol.Location 15 | 16 | internal fun TextRange.toLspLocation(file: VirtualFile, document: Document): Location { 17 | return Location(DocumentUri(file.uri), toLspRange(document)) 18 | } 19 | 20 | context(LSAnalysisContext) 21 | internal fun PsiElement.getLspLocation(): Location? { 22 | val textRange = textRange ?: return null 23 | val virtualFile = containingFile.virtualFile 24 | val document = requireNotNull(virtualFile.findDocument()) { 25 | "Got PSI which for which we can't get document: ${virtualFile}" 26 | } 27 | return textRange.toLspLocation(virtualFile, document) 28 | } 29 | 30 | context(LSAnalysisContext) 31 | fun PsiElement.getLspLocationForDefinition(): Location? { 32 | (this as? PsiNameIdentifierOwner)?.nameIdentifier?.getLspLocation()?.let { return it } 33 | return getLspLocation() 34 | } -------------------------------------------------------------------------------- /features-impl/common/src/com/jetbrains/ls/api/features/impl/common/workspace/LSExportWorkspaceCommandDescriptorProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.workspace 3 | 4 | import com.jetbrains.ls.api.features.commands.LSCommandDescriptor 5 | import com.jetbrains.ls.api.features.commands.LSCommandDescriptorProvider 6 | import com.jetbrains.ls.imports.json.toJson 7 | import com.jetbrains.lsp.implementation.throwLspError 8 | import com.jetbrains.lsp.protocol.Commands.ExecuteCommand 9 | import com.jetbrains.lsp.protocol.ErrorCodes 10 | import kotlinx.coroutines.Dispatchers 11 | import kotlinx.coroutines.withContext 12 | import kotlinx.serialization.json.JsonPrimitive 13 | import kotlin.io.path.Path 14 | import kotlin.io.path.writeText 15 | 16 | object LSExportWorkspaceCommandDescriptorProvider : LSCommandDescriptorProvider { 17 | override val commandDescriptors: List = listOf( 18 | LSCommandDescriptor("Export Workspace", "exportWorkspace") { arguments -> 19 | if (arguments.size != 1) { 20 | throwLspError(ExecuteCommand, "Expected 1 argument, got: ${arguments.size}", Unit, ErrorCodes.InvalidParams, null) 21 | } 22 | val workspacePath = (arguments.first() as? JsonPrimitive)?.content?.let { Path(it) } 23 | ?: throwLspError(ExecuteCommand, "Invalid argument, expected a string, got: ${arguments[0]}", Unit, ErrorCodes.InvalidParams, null) 24 | val workspaceModelPath = workspacePath.resolve("workspace.json") 25 | 26 | withContext(Dispatchers.IO) { 27 | val storage = workspaceStructure.getEntityStorage() 28 | val json = toJson(storage, workspacePath) 29 | workspaceModelPath.writeText(json) 30 | } 31 | 32 | JsonPrimitive(null) 33 | } 34 | ) 35 | } -------------------------------------------------------------------------------- /features-impl/kotlin/resources/META-INF/language-server/features/kotlin/codeActions.xml: -------------------------------------------------------------------------------- 1 | 2 | features/kotlin/codeActions 3 | JetBrains 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 24 | 26 | 27 | -------------------------------------------------------------------------------- /features-impl/kotlin/resources/META-INF/language-server/features/kotlin/completion.xml: -------------------------------------------------------------------------------- 1 | 2 | features/kotlin/completion 3 | JetBrains 4 | 5 | 6 | 10 | 11 | 13 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /features-impl/kotlin/resources/META-INF/language-server/features/kotlin/lsApiKotlinImpl.xml: -------------------------------------------------------------------------------- 1 | 2 | features/kotlin/core 3 | JetBrains 4 | 5 | 6 | 8 | 9 | 11 | 12 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /features-impl/kotlin/resources/META-INF/language-server/features/kotlin/usages.xml: -------------------------------------------------------------------------------- 1 | 2 | features/kotlin/usages 3 | JetBrains 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/apiImpl/lsApiKotlinImplPlugin.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.apiImpl 3 | 4 | import com.intellij.ide.plugins.IdeaPluginDescriptorImpl 5 | import com.intellij.ide.plugins.PluginMainDescriptor 6 | import com.jetbrains.ls.api.features.utils.ijPluginByXml 7 | 8 | internal val lsApiKotlinImpl: PluginMainDescriptor = ijPluginByXml("META-INF/language-server/features/kotlin/lsApiKotlinImpl.xml") -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/apiImpl/textEdits/KotlinFileForModificationFactory.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.apiImpl.textEdits 3 | 4 | import com.intellij.psi.PsiFile 5 | import com.jetbrains.ls.api.features.textEdits.PsiFileTextEditsCollector 6 | import org.jetbrains.kotlin.analysis.api.projectStructure.contextModule 7 | import org.jetbrains.kotlin.idea.base.projectStructure.getKaModule 8 | import org.jetbrains.kotlin.psi.KtPsiFactory 9 | 10 | internal class KotlinFileForModificationFactory : PsiFileTextEditsCollector.FileForModificationFactory { 11 | override fun createFileForModifications(file: PsiFile, setOriginalFie: Boolean): PsiFile { 12 | val project = file.project 13 | val copyKtFile = KtPsiFactory(project, markGenerated = true, eventSystemEnabled = true).createFile(file.text) 14 | copyKtFile.contextModule = file.getKaModule(project, useSiteModule = null) 15 | if (setOriginalFie) { 16 | copyKtFile.originalFile = file 17 | } 18 | return copyKtFile 19 | } 20 | } -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/codeActions/NoOpReferenceShortener.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.codeActions 3 | 4 | import com.intellij.openapi.util.TextRange 5 | import com.intellij.psi.PsiElement 6 | import org.jetbrains.kotlin.analysis.api.components.ShortenOptions 7 | import org.jetbrains.kotlin.idea.base.codeInsight.ShortenReferencesFacility 8 | import org.jetbrains.kotlin.psi.KtElement 9 | import org.jetbrains.kotlin.psi.KtFile 10 | 11 | internal class NoOpReferenceShortener : ShortenReferencesFacility { 12 | override fun shorten(file: KtFile, range: TextRange, shortenOptions: ShortenOptions) {} 13 | 14 | override fun shorten(element: KtElement, shortenOptions: ShortenOptions): PsiElement? { 15 | return element 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/codeActions/kotlinCodeActionsPlugin.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.codeActions 3 | 4 | import com.intellij.ide.plugins.PluginMainDescriptor 5 | import com.jetbrains.ls.api.features.utils.ijPluginByXml 6 | import org.jetbrains.kotlin.idea.codeInsight.inspections.shared.KotlinUnusedImportInspection 7 | import org.jetbrains.kotlin.idea.k2.codeinsight.inspections.UsePropertyAccessSyntaxInspection 8 | 9 | internal val kotlinCodeActionsPlugins: List = listOf( 10 | ijPluginByXml("META-INF/language-server/features/kotlin/codeActions.xml"), 11 | ijPluginByXml("kotlin.code-insight.inspections.k2.xml", classForClasspath = UsePropertyAccessSyntaxInspection::class.java), 12 | ijPluginByXml("kotlin.code-insight.inspections.shared.xml", classForClasspath = KotlinUnusedImportInspection::class.java), 13 | ) -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/codeStyle/kotlinCodeStylePlugin.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.codeStyle 3 | 4 | import com.intellij.ide.plugins.PluginMainDescriptor 5 | import com.jetbrains.ls.api.features.utils.ijPluginByXml 6 | import org.jetbrains.kotlin.idea.plugin.common.KotlinPluginCommonClassForClassPath 7 | 8 | internal val kotlinCodeStylePlugin: PluginMainDescriptor = 9 | ijPluginByXml( 10 | "/META-INF/formatter.xml", 11 | classForClasspath = KotlinPluginCommonClassForClassPath::class.java, 12 | useFakePluginId = true, 13 | ) -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/completion/LSCompletionItemKindProviderKotlinImpl.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.completion 3 | 4 | import com.intellij.psi.* 5 | import com.jetbrains.ls.api.features.completion.LSCompletionItemKindProvider 6 | import com.jetbrains.lsp.protocol.CompletionItemKind 7 | import org.jetbrains.kotlin.asJava.unwrapped 8 | import org.jetbrains.kotlin.lexer.KtTokens 9 | import org.jetbrains.kotlin.psi.* 10 | import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject 11 | 12 | internal class LSCompletionItemKindProviderKotlinImpl : LSCompletionItemKindProvider { 13 | override fun getKind(psi: PsiElement): CompletionItemKind? = 14 | when (val psi = psi.unwrapped) { 15 | is KtConstructor<*> -> CompletionItemKind.Constructor 16 | is KtFunction -> when { 17 | psi.hasModifier(KtTokens.OPERATOR_KEYWORD) -> CompletionItemKind.Operator 18 | psi.containingClassOrObject != null -> CompletionItemKind.Method 19 | else -> CompletionItemKind.Function 20 | } 21 | 22 | is KtProperty -> when { 23 | psi.hasModifier(KtTokens.CONST_KEYWORD) -> CompletionItemKind.Constant 24 | psi.isLocal -> CompletionItemKind.Variable 25 | else -> CompletionItemKind.Property 26 | } 27 | 28 | is KtParameter -> CompletionItemKind.Variable 29 | is KtClass -> when { 30 | psi.isData() -> CompletionItemKind.Struct 31 | psi.isInterface() -> CompletionItemKind.Interface 32 | psi.isEnum() -> CompletionItemKind.Enum 33 | psi is KtEnumEntry -> CompletionItemKind.EnumMember 34 | else -> CompletionItemKind.Class 35 | } 36 | 37 | is KtTypeParameter -> CompletionItemKind.TypeParameter 38 | else -> null 39 | } 40 | } -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/completion/kotlinCompletionPlugin.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.completion 3 | 4 | import com.intellij.ide.plugins.PluginMainDescriptor 5 | import com.jetbrains.ls.api.features.utils.ijPluginByXml 6 | 7 | internal val kotlinCompletionPlugin: PluginMainDescriptor = ijPluginByXml( 8 | "META-INF/language-server/features/kotlin/completion.xml" 9 | ) -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/completion/rekot/completionUtils.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.completion.rekot 3 | 4 | internal const val COMPLETION_FAKE_IDENTIFIER = "RWwgUHN5IEtvbmdyb28g" 5 | 6 | internal fun matchesPrefix(prefix: String?, item: String): Boolean { 7 | if (prefix == null) return true 8 | return item.contains(prefix, ignoreCase = true) 9 | } 10 | -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/definitions/LSKotlinPackageDefinitionProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.definitions 3 | 4 | import com.intellij.openapi.application.runReadAction 5 | import com.intellij.openapi.vfs.findDocument 6 | import com.intellij.openapi.vfs.findPsiFile 7 | import com.intellij.psi.PsiPackage 8 | import com.intellij.psi.search.EverythingGlobalScope 9 | import com.intellij.psi.stubs.StubIndex 10 | import com.jetbrains.ls.api.core.LSServer 11 | import com.jetbrains.ls.api.core.util.findVirtualFile 12 | import com.jetbrains.ls.api.core.util.isFromLibrary 13 | import com.jetbrains.ls.api.core.util.offsetByPosition 14 | import com.jetbrains.ls.api.core.util.uri 15 | import com.jetbrains.ls.api.features.definition.LSDefinitionProvider 16 | import com.jetbrains.ls.api.features.impl.common.kotlin.language.LSKotlinLanguage 17 | import com.jetbrains.ls.api.features.language.LSLanguage 18 | import com.jetbrains.lsp.protocol.DefinitionParams 19 | import com.jetbrains.lsp.protocol.DocumentUri 20 | import com.jetbrains.lsp.protocol.Location 21 | import com.jetbrains.lsp.protocol.Range 22 | import kotlinx.coroutines.flow.Flow 23 | import kotlinx.coroutines.flow.flow 24 | import org.jetbrains.kotlin.idea.stubindex.KotlinExactPackagesIndex 25 | 26 | internal object LSKotlinPackageDefinitionProvider : LSDefinitionProvider { 27 | override val supportedLanguages: Set get() = setOf(LSKotlinLanguage) 28 | 29 | context(LSServer@LSServer) 30 | override fun provideDefinitions(params: DefinitionParams): Flow = flow { 31 | val uri = params.textDocument.uri.uri 32 | withAnalysisContext { 33 | runReadAction { 34 | val file = uri.findVirtualFile() ?: return@runReadAction emptyList() 35 | val psiFile = file.findPsiFile(project) ?: return@runReadAction emptyList() 36 | val document = file.findDocument() ?: return@runReadAction emptyList() 37 | val offset = document.offsetByPosition(params.position) 38 | val reference = psiFile.findReferenceAt(offset) ?: return@runReadAction emptyList() 39 | val psiPackage = (reference.resolve() as? PsiPackage) ?: return@runReadAction emptyList() 40 | 41 | // A hackish replacement for PsiPackage.directories which is not working because of the missing logic in FakePackageIndexImpl. 42 | StubIndex.getInstance() 43 | .getContainingFilesIterator(KotlinExactPackagesIndex.NAME, psiPackage.qualifiedName, project, EverythingGlobalScope()) 44 | .asSequence() 45 | .filterNot { it.isFromLibrary() } 46 | .mapNotNull { it.parent?.uri?.let { Location(DocumentUri(it), Range.BEGINNING) } } 47 | .toList() 48 | } 49 | }.forEach { emit(it) } 50 | } 51 | } -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/diagnostics/compiler/KotlinCompilerDiagnosticData.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.diagnostics.compiler 3 | 4 | import com.intellij.openapi.vfs.VirtualFile 5 | import com.jetbrains.ls.api.core.LSAnalysisContext 6 | import com.jetbrains.ls.api.core.LSServer 7 | import com.jetbrains.ls.api.features.impl.common.diagnostics.DiagnosticData 8 | import com.jetbrains.ls.api.features.impl.common.diagnostics.DiagnosticSource 9 | import com.jetbrains.ls.api.features.utils.PsiSerializablePointer 10 | import kotlinx.serialization.Serializable 11 | import org.jetbrains.kotlin.analysis.api.diagnostics.KaDiagnosticWithPsi 12 | 13 | @Serializable 14 | internal data class KotlinCompilerDiagnosticData( 15 | val severityName: String, 16 | val diagnosticClass: String, 17 | val psi: PsiSerializablePointer, 18 | ) : DiagnosticData { 19 | override val diagnosticSource: DiagnosticSource = source 20 | 21 | fun matches(kaDiagnostic: KaDiagnosticWithPsi<*>): Boolean { 22 | if (kaDiagnostic::class.java.name != diagnosticClass) return false 23 | if (kaDiagnostic.severity.name != severityName) return false 24 | if (!psi.matches(kaDiagnostic.psi)) return false 25 | return true 26 | } 27 | 28 | companion object { 29 | val source: DiagnosticSource = DiagnosticSource("kotlinCompilerDiagnostic") 30 | 31 | context(LSAnalysisContext, LSServer) 32 | fun create(diagnostic: KaDiagnosticWithPsi<*>, file: VirtualFile): KotlinCompilerDiagnosticData { 33 | val psi = PsiSerializablePointer.create(diagnostic.psi, file) 34 | return KotlinCompilerDiagnosticData( 35 | severityName = diagnostic.severity.name, 36 | diagnosticClass = diagnostic::class.java.name, 37 | psi = psi, 38 | ) 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/diagnostics/compiler/KotlinCompilerDiagnosticQuickfixData.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.diagnostics.compiler 3 | 4 | import com.intellij.codeInsight.intention.IntentionAction 5 | import kotlinx.serialization.Serializable 6 | 7 | @Serializable 8 | internal data class KotlinCompilerDiagnosticQuickfixData( 9 | val text: String, 10 | val familyName: String, 11 | val intentionActionClass: String, 12 | ) { 13 | 14 | companion object { 15 | fun createByIntentionAction( 16 | intentionAction: IntentionAction, 17 | ): KotlinCompilerDiagnosticQuickfixData { 18 | return KotlinCompilerDiagnosticQuickfixData( 19 | text = intentionAction.text, 20 | familyName = intentionAction.familyName, 21 | intentionActionClass = intentionAction::class.java.name, 22 | ) 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/diagnostics/compiler/LSKotlinCompilerDiagnosticsProvider.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.diagnostics.compiler 3 | 4 | import com.intellij.openapi.application.runReadAction 5 | import com.intellij.openapi.editor.Document 6 | import com.intellij.openapi.vfs.VirtualFile 7 | import com.intellij.openapi.vfs.findDocument 8 | import com.intellij.openapi.vfs.findPsiFile 9 | import com.jetbrains.ls.api.core.LSAnalysisContext 10 | import com.jetbrains.ls.api.core.LSServer 11 | import com.jetbrains.ls.api.core.util.findVirtualFile 12 | import com.jetbrains.ls.api.core.util.toLspRange 13 | import com.jetbrains.ls.api.features.diagnostics.LSDiagnosticProvider 14 | import com.jetbrains.ls.api.features.impl.common.kotlin.language.LSKotlinLanguage 15 | import com.jetbrains.ls.api.features.language.LSLanguage 16 | import com.jetbrains.lsp.protocol.Diagnostic 17 | import com.jetbrains.lsp.protocol.DocumentDiagnosticParams 18 | import com.jetbrains.lsp.protocol.LSP 19 | import com.jetbrains.lsp.protocol.StringOrInt 20 | import kotlinx.coroutines.flow.Flow 21 | import kotlinx.coroutines.flow.flow 22 | import kotlinx.serialization.json.encodeToJsonElement 23 | import org.jetbrains.kotlin.analysis.api.KaSession 24 | import org.jetbrains.kotlin.analysis.api.analyze 25 | import org.jetbrains.kotlin.analysis.api.components.KaDiagnosticCheckerFilter 26 | import org.jetbrains.kotlin.analysis.api.diagnostics.KaDiagnosticWithPsi 27 | import org.jetbrains.kotlin.psi.KtFile 28 | 29 | internal object LSKotlinCompilerDiagnosticsProvider : LSDiagnosticProvider { 30 | override val supportedLanguages: Set = setOf(LSKotlinLanguage) 31 | 32 | context(LSServer) 33 | override fun getDiagnostics(params: DocumentDiagnosticParams): Flow = flow { 34 | val uri = params.textDocument.uri.uri 35 | withAnalysisContext { 36 | runReadAction { 37 | val file = uri.findVirtualFile() ?: return@runReadAction emptyList() 38 | val ktFile = file.findPsiFile(project) as? KtFile ?: return@runReadAction emptyList() 39 | val document = file.findDocument() ?: return@runReadAction emptyList() 40 | analyze(ktFile) { 41 | val diagnostics = ktFile.collectDiagnostics(filter = KaDiagnosticCheckerFilter.ONLY_COMMON_CHECKERS) 42 | diagnostics.flatMap { it.toLsp(document, file) } 43 | } 44 | } 45 | }.forEach { emit(it) } 46 | } 47 | } 48 | 49 | context(KaSession, LSAnalysisContext, LSServer) 50 | private fun KaDiagnosticWithPsi<*>.toLsp(document: Document, file: VirtualFile): List { 51 | val data = KotlinCompilerDiagnosticData.create(this, file) 52 | return textRanges.map { textRange -> 53 | Diagnostic( 54 | textRange.toLspRange(document), 55 | severity = severity.toLsp(), 56 | code = StringOrInt.string(factoryName), 57 | source = "Kotlin", 58 | message = defaultMessage, 59 | tags = emptyList(), 60 | data = LSP.json.encodeToJsonElement(data), 61 | relatedInformation = emptyList(), 62 | ) 63 | } 64 | } -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/diagnostics/compiler/kotlinCompilerDiagnosticUtils.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.diagnostics.compiler 3 | 4 | import com.jetbrains.lsp.protocol.DiagnosticSeverity 5 | import org.jetbrains.kotlin.analysis.api.diagnostics.KaSeverity 6 | 7 | internal fun KaSeverity.toLsp(): DiagnosticSeverity = when (this) { 8 | KaSeverity.ERROR -> DiagnosticSeverity.Error 9 | KaSeverity.WARNING -> DiagnosticSeverity.Warning 10 | KaSeverity.INFO -> DiagnosticSeverity.Information 11 | } -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/hover/LSMarkdownDocProviderKotlinImpl.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.hover 3 | 4 | import com.intellij.psi.PsiElement 5 | import com.jetbrains.ls.api.features.impl.common.hover.AbstractLSHoverProvider 6 | import com.jetbrains.ls.api.features.impl.common.hover.markdownMultilineCode 7 | import com.jetbrains.ls.api.features.impl.common.kotlin.language.LSKotlinLanguage 8 | import org.jetbrains.kotlin.asJava.unwrapped 9 | import org.jetbrains.kotlin.psi.KtDeclaration 10 | 11 | internal class LSMarkdownDocProviderKotlinImpl : AbstractLSHoverProvider.LSMarkdownDocProvider { 12 | override fun getMarkdownDoc(element: PsiElement): String? { 13 | val ktElement = element.unwrapped as? KtDeclaration ?: return null 14 | val kdDocText = ktElement.docComment?.text ?: return null 15 | return markdownMultilineCode( 16 | kdDocText.formatKdoc(), 17 | language = LSKotlinLanguage.lspName 18 | ) 19 | } 20 | 21 | private fun String.formatKdoc(): String { 22 | val trimmedLines = trim().lines().map { it.trim() }.filter { it.isNotEmpty() } 23 | return trimmedLines.joinToString(separator = "\n") { if (it.startsWith("/*")) it else " $it" } 24 | } 25 | } -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/language/LSKotlinLanguage.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.language 3 | 4 | import com.jetbrains.ls.api.features.language.LSLanguage 5 | import org.jetbrains.kotlin.idea.KotlinLanguage 6 | 7 | val LSKotlinLanguage: LSLanguage = LSLanguage( 8 | lspName = "kotlin", 9 | intellijLanguage = KotlinLanguage.INSTANCE, 10 | extensions = listOf("kt"), 11 | ) -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/symbols/LSDocumentSymbolProviderKotlin.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.symbols 3 | 4 | import com.intellij.psi.PsiElement 5 | import com.jetbrains.ls.api.features.impl.common.symbols.AbstractLSDocumentSymbolProvider 6 | import com.jetbrains.ls.api.features.impl.common.kotlin.language.LSKotlinLanguage 7 | import com.jetbrains.ls.api.features.language.LSLanguage 8 | import com.jetbrains.lsp.protocol.SymbolKind 9 | import org.jetbrains.kotlin.psi.KtClassInitializer 10 | import org.jetbrains.kotlin.psi.KtClassOrObject 11 | import org.jetbrains.kotlin.psi.KtDeclarationContainer 12 | import org.jetbrains.kotlin.psi.KtNamedDeclaration 13 | import org.jetbrains.kotlin.psi.KtProperty 14 | import org.jetbrains.kotlin.psi.KtPropertyAccessor 15 | 16 | object LSDocumentSymbolProviderKotlin: AbstractLSDocumentSymbolProvider() { 17 | override val supportedLanguages: Set = setOf(LSKotlinLanguage) 18 | 19 | override fun getName(element: PsiElement): String? = 20 | when (element) { 21 | is KtClassInitializer -> "" 22 | is KtPropertyAccessor -> 23 | when { 24 | element.isGetter -> "get" 25 | else -> "set" 26 | } 27 | else -> super.getName(element) 28 | } 29 | 30 | 31 | override fun getKind(element: PsiElement): SymbolKind? = 32 | element.getKind() 33 | 34 | override fun isDeprecated(element: PsiElement): Boolean = 35 | // TODO: Something more robust 36 | (element as? KtNamedDeclaration)?.annotationEntries?.any { it.shortName.toString() == "Deprecated" } == true 37 | 38 | override fun getNestedDeclarations(element: PsiElement): List = 39 | when (element) { 40 | is KtClassOrObject -> 41 | element.primaryConstructorParameters.filter { it.valOrVarKeyword != null } + 42 | listOfNotNull(element.primaryConstructor) + 43 | element.declarations 44 | is KtDeclarationContainer -> element.declarations 45 | is KtProperty -> element.accessors 46 | else -> emptyList() 47 | } 48 | } -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/symbols/LSWorkspaceSymbolProviderKotlinImpl.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.symbols 3 | 4 | import com.intellij.navigation.ChooseByNameContributor 5 | import com.intellij.navigation.NavigationItem 6 | import com.intellij.navigation.PsiElementNavigationItem 7 | import com.intellij.psi.util.parentsOfType 8 | import com.jetbrains.ls.api.core.LSAnalysisContext 9 | import com.jetbrains.ls.api.core.LSServer 10 | import com.jetbrains.ls.api.features.impl.common.utils.getLspLocationForDefinition 11 | import com.jetbrains.ls.api.features.impl.common.symbols.AbstractLSWorkspaceSymbolProvider 12 | import com.jetbrains.lsp.protocol.WorkspaceSymbol 13 | import org.jetbrains.kotlin.idea.goto.KotlinGotoClassContributor 14 | import org.jetbrains.kotlin.idea.goto.KotlinGotoFunctionSymbolContributor 15 | import org.jetbrains.kotlin.idea.goto.KotlinGotoPropertySymbolContributor 16 | import org.jetbrains.kotlin.idea.goto.KotlinGotoTypeAliasContributor 17 | import org.jetbrains.kotlin.psi.KtNamedDeclaration 18 | 19 | internal object LSWorkspaceSymbolProviderKotlinImpl : AbstractLSWorkspaceSymbolProvider() { 20 | override fun getContributors(): List = listOf( 21 | KotlinGotoClassContributor(), 22 | KotlinGotoTypeAliasContributor(), 23 | KotlinGotoFunctionSymbolContributor(), 24 | KotlinGotoPropertySymbolContributor(), 25 | ) 26 | 27 | context(LSServer, LSAnalysisContext) 28 | override fun createWorkspaceSymbol( 29 | item: NavigationItem, 30 | contributor: ChooseByNameContributor 31 | ): WorkspaceSymbol? { 32 | val ktNamedDeclaration = when (item) { 33 | is PsiElementNavigationItem -> item.targetElement as? KtNamedDeclaration 34 | is KtNamedDeclaration -> item 35 | else -> null 36 | } ?: return null 37 | return WorkspaceSymbol( 38 | item.name ?: return null, 39 | kind = ktNamedDeclaration.getKind() ?: return null, 40 | tags = null, // todo handle deprecations 41 | containerName = ktNamedDeclaration.getClosestContainerQualifiedName(), 42 | location = ktNamedDeclaration.getLspLocationForDefinition() ?: return null, 43 | data = null, 44 | ) 45 | } 46 | 47 | private fun KtNamedDeclaration.getClosestContainerQualifiedName(): String { 48 | return parentsOfType(withSelf = false) 49 | .firstNotNullOfOrNull { it.fqName?.asString() } 50 | ?: containingKtFile.packageFqName.asString() 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/symbols/kinds.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.symbols 3 | 4 | import com.intellij.psi.PsiElement 5 | import com.jetbrains.lsp.protocol.SymbolKind 6 | import org.jetbrains.kotlin.lexer.KtTokens 7 | import org.jetbrains.kotlin.psi.KtClass 8 | import org.jetbrains.kotlin.psi.KtClassInitializer 9 | import org.jetbrains.kotlin.psi.KtConstructor 10 | import org.jetbrains.kotlin.psi.KtEnumEntry 11 | import org.jetbrains.kotlin.psi.KtFile 12 | import org.jetbrains.kotlin.psi.KtNamedFunction 13 | import org.jetbrains.kotlin.psi.KtObjectDeclaration 14 | import org.jetbrains.kotlin.psi.KtParameter 15 | import org.jetbrains.kotlin.psi.KtProperty 16 | import org.jetbrains.kotlin.psi.KtPropertyAccessor 17 | import org.jetbrains.kotlin.psi.KtTypeAlias 18 | import org.jetbrains.kotlin.psi.KtTypeParameter 19 | import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject 20 | 21 | internal fun PsiElement.getKind(): SymbolKind? = when (this) { 22 | is KtFile -> SymbolKind.File 23 | is KtEnumEntry -> SymbolKind.EnumMember 24 | is KtClass -> when { 25 | isInterface() -> SymbolKind.Interface 26 | isEnum() -> SymbolKind.Enum 27 | isData() -> SymbolKind.Struct 28 | else -> SymbolKind.Class 29 | } 30 | 31 | is KtObjectDeclaration -> SymbolKind.Object 32 | is KtConstructor<*> -> SymbolKind.Constructor 33 | is KtClassInitializer -> SymbolKind.Constructor 34 | is KtNamedFunction -> when { 35 | containingClassOrObject != null -> SymbolKind.Method 36 | hasModifier(KtTokens.OPERATOR_KEYWORD) -> SymbolKind.Operator 37 | else -> SymbolKind.Function 38 | } 39 | 40 | is KtProperty -> when { 41 | isLocal -> SymbolKind.Variable 42 | hasModifier(KtTokens.CONST_KEYWORD) -> SymbolKind.Constant 43 | else -> SymbolKind.Property 44 | } 45 | is KtPropertyAccessor -> SymbolKind.Method 46 | 47 | is KtTypeAlias -> SymbolKind.Class 48 | 49 | is KtParameter -> SymbolKind.Variable 50 | is KtTypeParameter -> SymbolKind.TypeParameter 51 | else -> null 52 | } -------------------------------------------------------------------------------- /features-impl/kotlin/src/com/jetbrains/ls/api/features/impl/common/kotlin/usages/kotlinUsagesIjPlugin.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.api.features.impl.common.kotlin.usages 3 | 4 | import com.intellij.ide.plugins.PluginMainDescriptor 5 | import com.jetbrains.ls.api.features.utils.ijPluginByXml 6 | import org.jetbrains.kotlin.idea.plugin.common.KotlinPluginCommonClassForClassPath 7 | import org.jetbrains.kotlin.idea.searching.kmp.KotlinK2ExpectActualSupport 8 | 9 | internal val kotlinUsagesIjPlugins: List by lazy { 10 | listOf( 11 | ijPluginByXml("META-INF/searching-base.xml", KotlinPluginCommonClassForClassPath::class.java, useFakePluginId = true), 12 | ijPluginByXml("META-INF/language-server/features/kotlin/usages.xml"), 13 | ijPluginByXml("kotlin.searching.k2.xml", KotlinK2ExpectActualSupport::class.java), 14 | ) 15 | } -------------------------------------------------------------------------------- /images/quickstart_sample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/images/quickstart_sample.gif -------------------------------------------------------------------------------- /kotlin-lsp/BUILD.bazel: -------------------------------------------------------------------------------- 1 | ### auto-generated section `build language-server.kotlin-lsp` start 2 | load("@community//build:compiler-options.bzl", "create_kotlinc_options") 3 | load("@rules_jvm//:jvm.bzl", "jvm_library") 4 | 5 | create_kotlinc_options( 6 | name = "custom", 7 | context_receivers = True, 8 | opt_in = ["org.jetbrains.kotlin.analysis.api.KaExperimentalApi"], 9 | when_guards = True 10 | ) 11 | 12 | jvm_library( 13 | name = "kotlin-lsp", 14 | module_name = "language-server.kotlin-lsp", 15 | visibility = ["//visibility:public"], 16 | srcs = glob(["src/**/*.kt", "src/**/*.java"], allow_empty = True), 17 | kotlinc_opts = ":custom", 18 | deps = [ 19 | "@lib//:kotlin-stdlib", 20 | "@community//fleet/lsp.protocol", 21 | "@community//fleet/util/core", 22 | "@community//platform/core-api:core", 23 | "@community//platform/core-impl", 24 | "@community//java/java-psi-api:psi", 25 | "@community//platform/util", 26 | "@lib//:kotlinx-coroutines-core", 27 | "@lib//:kotlinx-serialization-json", 28 | "@lib//:kotlinx-serialization-core", 29 | "@lib//:kotlinc-kotlin-compiler-common", 30 | "@community//platform/workspace/storage", 31 | "//language-server/community/api.core", 32 | "//language-server/api.impl.analyzer", 33 | "@lib//:kotlinc-analysis-api", 34 | "@lib//:kotlinc-analysis-api-k2", 35 | "@community//java/java-impl:impl", 36 | "@community//java/openapi:java", 37 | "@community//plugins/kotlin/base/plugin", 38 | "//language-server/community/api.features", 39 | "@community//platform/editor-ui-ex:editor-ex", 40 | "@community//plugins/kotlin/fir", 41 | "@community//plugins/kotlin/base/project-structure", 42 | "//language-server/community/features-impl/common", 43 | "//language-server/community/features-impl/kotlin", 44 | "//language-server/analyzer", 45 | "@community//plugins/kotlin/base/code-insight", 46 | "@community//plugins/kotlin/kotlin.searching/base", 47 | "//language-server/community/workspace-import:language-server-project-import", 48 | "@community//platform/workspace/jps", 49 | "@lib//:clikt", 50 | "@community//fleet/rhizomedb", 51 | "@community//fleet/kernel", 52 | "@community//platform/service-container", 53 | ] 54 | ) 55 | ### auto-generated section `build language-server.kotlin-lsp` end -------------------------------------------------------------------------------- /kotlin-lsp/README.md: -------------------------------------------------------------------------------- 1 | TODO -------------------------------------------------------------------------------- /kotlin-lsp/src/com/jetbrains/ls/kotlinLsp/connection/Client.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.kotlinLsp.connection 3 | 4 | import com.jetbrains.lsp.implementation.LspClient 5 | import com.jetbrains.lsp.protocol.TraceValue 6 | import kotlinx.coroutines.ThreadContextElement 7 | import kotlinx.coroutines.asContextElement 8 | 9 | data class Client( 10 | val lspClient: LspClient, 11 | val trace: TraceValue? = null, 12 | ) { 13 | companion object { 14 | val current: Client? 15 | get() = ClientConnectionHolder.ThreadBound.get()?.connection 16 | 17 | fun contextElement(lspClient: LspClient): ThreadContextElement<*> { 18 | return ClientConnectionHolder.ThreadBound.asContextElement( 19 | ClientConnectionHolder(Client(lspClient)) 20 | ) 21 | } 22 | 23 | fun update(update: (Client) -> Client) { 24 | val holder = ClientConnectionHolder.ThreadBound.get() ?: error("Not inside connection scope") 25 | holder.connection = update(holder.connection) 26 | } 27 | } 28 | } 29 | 30 | private class ClientConnectionHolder( 31 | @Volatile var connection: Client, 32 | ) { 33 | companion object { 34 | val ThreadBound: ThreadLocal = ThreadLocal() 35 | } 36 | } -------------------------------------------------------------------------------- /kotlin-lsp/src/com/jetbrains/ls/kotlinLsp/requests/core/fileUpdates.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.kotlinLsp.requests.core 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.lsp.implementation.LspHandlersBuilder 6 | import com.jetbrains.lsp.protocol.DocumentSync 7 | 8 | context(LSServer) 9 | internal fun LspHandlersBuilder.fileUpdateRequests() { 10 | notification(DocumentSync.DidOpen) { didOpen -> 11 | documents.didOpen( 12 | uri = didOpen.textDocument.uri.uri, 13 | fileText = didOpen.textDocument.text, 14 | version = didOpen.textDocument.version.toLong(), 15 | languageId = didOpen.textDocument.languageId 16 | ) 17 | } 18 | notification(DocumentSync.DidClose) { didClose -> 19 | documents.didClose(didClose.textDocument.uri.uri) 20 | } 21 | 22 | notification(DocumentSync.DidChange) { didChange -> 23 | documents.didChange( 24 | uri = didChange.textDocument.uri.uri, 25 | changes = didChange.contentChanges, 26 | ) 27 | } 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /kotlin-lsp/src/com/jetbrains/ls/kotlinLsp/requests/core/shutdown.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.kotlinLsp.requests.core 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.lsp.implementation.LspHandlersBuilder 7 | import com.jetbrains.lsp.protocol.ExitNotificationType 8 | import com.jetbrains.lsp.protocol.Shutdown 9 | import kotlinx.coroutines.CompletableDeferred 10 | 11 | context(LSServer, LSConfiguration) 12 | internal fun LspHandlersBuilder.shutdownRequest(clientMode: Boolean, exitSignal: CompletableDeferred) { 13 | request(Shutdown) { 14 | // TODO All the requests and notifications after this one should return InvalidRequest 15 | // https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#shutdown 16 | } 17 | notification(ExitNotificationType) { 18 | if (clientMode) { 19 | exitSignal.complete(Unit) 20 | } else { 21 | // do nothing, keep the server running 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /kotlin-lsp/src/com/jetbrains/ls/kotlinLsp/requests/core/trace.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.kotlinLsp.requests.core 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.ls.kotlinLsp.connection.Client 7 | import com.jetbrains.lsp.implementation.LspHandlersBuilder 8 | import com.jetbrains.lsp.protocol.SetTraceNotificationType 9 | 10 | context(LSServer, LSConfiguration) 11 | internal fun LspHandlersBuilder.setTraceNotification() { 12 | notification(SetTraceNotificationType) { traceParams -> 13 | Client.update { it.copy(trace = traceParams) } 14 | } 15 | } -------------------------------------------------------------------------------- /kotlin-lsp/src/com/jetbrains/ls/kotlinLsp/requests/features.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.kotlinLsp.requests 3 | 4 | import com.jetbrains.ls.api.core.LSServer 5 | import com.jetbrains.ls.api.features.LSConfiguration 6 | import com.jetbrains.ls.api.features.codeActions.LSCodeActions 7 | import com.jetbrains.ls.api.features.commands.LSCommand 8 | import com.jetbrains.ls.api.features.completion.LSCompletion 9 | import com.jetbrains.ls.api.features.definition.LSDefinition 10 | import com.jetbrains.ls.api.features.diagnostics.LSDiagnostic 11 | import com.jetbrains.ls.api.features.symbols.LSDocumentSymbols 12 | import com.jetbrains.ls.api.features.hover.LSHover 13 | import com.jetbrains.ls.api.features.references.LSReferences 14 | import com.jetbrains.ls.api.features.semanticTokens.LSSemanticTokens 15 | import com.jetbrains.ls.api.features.symbols.LSWorkspaceSymbols 16 | import com.jetbrains.lsp.implementation.LspHandlersBuilder 17 | import com.jetbrains.lsp.protocol.* 18 | import com.jetbrains.lsp.protocol.CodeActions.CodeActionRequest 19 | import com.jetbrains.lsp.protocol.Commands.ExecuteCommand 20 | import com.jetbrains.lsp.protocol.Diagnostics.DocumentDiagnosticRequestType 21 | import com.jetbrains.lsp.protocol.SemanticTokensRequests.SemanticTokensFullRequest 22 | import com.jetbrains.lsp.protocol.WorkspaceSymbolRequests.WorkspaceSymbolRequest 23 | 24 | context(LSServer, LSConfiguration) 25 | internal fun LspHandlersBuilder.features() { 26 | request(CodeActionRequest) { LSCodeActions.getCodeActions(it) } 27 | request(ExecuteCommand) { LSCommand.executeCommand(it) } 28 | request(CompletionRequestType) { LSCompletion.getCompletion(it) } 29 | request(CompletionResolveRequestType) { LSCompletion.resolveCompletion(it) } 30 | request(DefinitionRequestType) { LSDefinition.getDefinition(it) } 31 | request(DocumentDiagnosticRequestType) { LSDiagnostic.getDiagnostics(it) } 32 | request(HoverRequestType) { LSHover.getHover(it) } 33 | request(ReferenceRequestType) { LSReferences.getReferences(it) } 34 | request(SemanticTokensFullRequest) { LSSemanticTokens.semanticTokensFull(it) } 35 | request(WorkspaceSymbolRequest) { LSWorkspaceSymbols.getSymbols(it) } 36 | request(DocumentSymbolRequest) { LSDocumentSymbols.getSymbols(it) } 37 | } -------------------------------------------------------------------------------- /kotlin-lsp/src/com/jetbrains/ls/kotlinLsp/util/systemInfo.kt: -------------------------------------------------------------------------------- 1 | package com.jetbrains.ls.kotlinLsp.util 2 | 3 | import com.intellij.openapi.diagnostic.Logger 4 | import com.intellij.openapi.util.SystemInfo 5 | import com.intellij.util.system.CpuArch 6 | import com.intellij.util.system.OS 7 | import com.jetbrains.lsp.implementation.LspClient 8 | import com.jetbrains.lsp.protocol.LogMessageNotification 9 | import com.jetbrains.lsp.protocol.LogMessageParams 10 | import com.jetbrains.lsp.protocol.MessageType 11 | 12 | internal fun getSystemInfo(): String = buildString { 13 | val runtime = Runtime.getRuntime() 14 | appendLine("System Info") 15 | appendLine(" os.name = ${OS.CURRENT.name}") 16 | appendLine(" os.version = ${OS.CURRENT.version}") 17 | appendLine(" cpu.arch = ${if (CpuArch.isEmulated()) "${CpuArch.CURRENT}(emulated)" else "${CpuArch.CURRENT}"}") 18 | appendLine(" cpu.number: " + runtime.availableProcessors()) 19 | appendLine(" java.version = ${SystemInfo.JAVA_RUNTIME_VERSION}") 20 | appendLine(" java.vm.vendor = ${SystemInfo.JAVA_VENDOR}") 21 | appendLine(" ram.xmx: ${runtime.maxMemory().bytesToMegabytes()}MB") 22 | } 23 | 24 | private fun Long.bytesToMegabytes(): Long = this / 1024L / 1024L 25 | 26 | internal fun logSystemInfo() { 27 | LOG.info(getSystemInfo()) 28 | } 29 | 30 | internal fun LspClient.sendSystemInfoToClient() { 31 | notify( 32 | LogMessageNotification, 33 | LogMessageParams(MessageType.Info, getSystemInfo()), 34 | ) 35 | } 36 | 37 | private val LOG = Logger.getInstance("SystemInfo") -------------------------------------------------------------------------------- /kotlin-vscode/.gitignore: -------------------------------------------------------------------------------- 1 | out/ 2 | server/extracted 3 | node_modules 4 | client/node_modules 5 | *.vsix -------------------------------------------------------------------------------- /kotlin-vscode/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Extension", 6 | "type": "extensionHost", 7 | "request": "launch", 8 | "args": [ 9 | "--extensionDevelopmentPath=${workspaceFolder}" 10 | ], 11 | "preLaunchTask": { 12 | "type": "npm", 13 | "script": "compile" 14 | } 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /kotlin-vscode/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | .gitignore 4 | out 5 | -------------------------------------------------------------------------------- /kotlin-vscode/README.md: -------------------------------------------------------------------------------- 1 | # Kotlin VSC extension 2 | 3 | Provides Kotlin language support for Visual Studio Code 4 | 5 | ## Features 6 | 7 | * Out-of-the box integration with Kotlin LSP 8 | * Kotlin files semantic highlighting 9 | * Kotlin diagnostics reporting 10 | * Basic Kotlin intentions and quickfixes 11 | * Auto-detection of Gradle projects 12 | 13 | ## Requirements 14 | 15 | * Java 17 and above 16 | * Visual Studio Code version 1.96.0 and above 17 | 18 | ## Getting started 19 | 20 | * Download the latest release bundle of VSC extension from [RELEASES.md](../RELEASES.md) 21 | * Install the extension into Visual Studio Code via `Extensions | More Action | Install from VSIX` 22 | * Alternatively, it is possible to drag-and-drop VSIX extension directly into `Extensions` tool window 23 | * Open folder with a Gradle JVM (**not** Kotlin Multiplatform) project 24 | * Enjoy! 25 | 26 | ## License 27 | 28 | Apache 2.0, see [LICENSE](LICENSE). 29 | -------------------------------------------------------------------------------- /kotlin-vscode/build.md: -------------------------------------------------------------------------------- 1 | # How to build Kotlin VSC extension 2 | 3 | ## Building release vsix 4 | 5 | 1. Run [LSP build](../../building/src/org/jetbrains/ls/building/BuildLSP.kt) 6 | 2. Set `export LSP_ZIP_PATH=../../../out/jps-artifacts/language_server_kotlin_lsp_zip/language-server.kotlin-lsp.zip` 7 | 3. `npx vsce package --baseContentUrl=https://github.com/Kotlin/kotlin-lsp/tree/main/kotlin-vscode` 8 | 4. The resulting `.vsix` file will be located in the current directory 9 | 10 | ## Development mode 11 | 12 | 1. Run 1-3 steps from the release steps 13 | 2. Run `npm install && npm run unpack-server` 14 | 3. Open this directory in VSC 15 | 4. Run extension (F5). LSP will start out of the box 16 | 5. [optional] If you want to easily debug LSP: 17 | 1. Run [LSP Server](language-server/language-server.kotlin-lsp/src/com/jetbrains/ls/lsp/LspServer.kt) 18 | 2. In the debug VSC, go to settings and specify LSP port (9999) in `kotlinLSP.dev.serverPort` 19 | 3. Reload VSC window using command `Developer: Reload window` 20 | -------------------------------------------------------------------------------- /kotlin-vscode/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "engines": { 3 | "vscode": "^1.97.0" 4 | }, 5 | "dependencies": { 6 | "vscode-languageclient": "9.0.1" 7 | }, 8 | "repository": { 9 | "directory": "." 10 | }, 11 | "devDependencies": { 12 | "@types/vscode": "^1.97.0", 13 | "@types/node": "^22.13.8", 14 | "vscode-tmgrammar-test": "^0.1.3" 15 | }, 16 | "scripts": { 17 | "test": "vscode-tmgrammar-snap --grammar ../syntaxes/kotlin.tmLanguage.json --scope source.kotlin testSources/tokenization/*.kt", 18 | "updateGrammarTests": "vscode-tmgrammar-snap --grammar ../syntaxes/kotlin.tmLanguage.json --scope source.kotlin --updateSnapshot testSources/tokenization/*.kt" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /kotlin-vscode/client/src/extension.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import {commands, type ExtensionContext, Uri, window, workspace} from "vscode" 3 | import {registerDecompiler} from "./decompiler" 4 | import { initLspClient, startLspClient } from './lspClient'; 5 | import { registerStatusBarItem } from './statusBar'; 6 | 7 | 8 | export const extensionId = 'kotlin' 9 | 10 | let _context : ExtensionContext | undefined 11 | 12 | export function getContext(): ExtensionContext { 13 | return _context!; 14 | } 15 | 16 | function registerExportWorkspaceToJsonCommand(context: ExtensionContext) { 17 | context.subscriptions.push(commands.registerCommand('jetbrains.exportWorkspaceToJson', async () => { 18 | if (workspace.rootPath === undefined) { 19 | await window.showErrorMessage('No workspace opened'); 20 | return; 21 | } 22 | const rootPath = workspace.rootPath as string; 23 | await commands.executeCommand('exportWorkspace', rootPath); 24 | const choice = await window.showInformationMessage('Exported workspace structure to workspace.json.', 'Open'); 25 | if (choice === 'Open') { 26 | const uri = Uri.file(path.join(rootPath, 'workspace.json')); 27 | const doc = await workspace.openTextDocument(uri); 28 | await window.showTextDocument(doc); 29 | } 30 | })); 31 | } 32 | 33 | 34 | export async function activate(context: ExtensionContext) { 35 | _context = context 36 | registerDecompiler(context) 37 | registerExportWorkspaceToJsonCommand(context) 38 | registerStatusBarItem() 39 | initLspClient() 40 | await startLspClient() 41 | } -------------------------------------------------------------------------------- /kotlin-vscode/client/src/java.ts: -------------------------------------------------------------------------------- 1 | import { workspace } from "vscode"; 2 | 3 | export function runWithJavaSupport(): boolean { 4 | return workspace.getConfiguration().get('kotlinLSP.javaSupport') || false 5 | } 6 | -------------------------------------------------------------------------------- /kotlin-vscode/client/src/statusBar.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import {State} from "vscode-languageclient/node"; 3 | import { getContext } from "./extension"; 4 | import { getLspClient, subscribeToClientEvent } from "./lspClient"; 5 | 6 | const TITLE = 'Kotlin' 7 | const LSP_TITLE = 'LSP' 8 | 9 | let statusBarItem: vscode.StatusBarItem | undefined; 10 | 11 | export function registerStatusBarItem() { 12 | statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100); 13 | statusBarItem.text = TITLE; 14 | statusBarItem.show(); 15 | updateView(); 16 | getContext().subscriptions.push(statusBarItem); 17 | subscribeToClientEvent(() => updateView()); 18 | } 19 | 20 | function updateView() { 21 | if (!statusBarItem) return; 22 | statusBarItem.tooltip = computeTooltip(); 23 | statusBarItem.text = computeText(); 24 | } 25 | 26 | function computeTooltip(): vscode.MarkdownString { 27 | const text = new vscode.MarkdownString() 28 | text.isTrusted = true; 29 | text.supportThemeIcons = true; 30 | text.supportHtml = true; 31 | 32 | const lspState = `
${getLspClientStatus()}
` 33 | text.appendMarkdown(` 34 |
35 |

Kotlin

36 | ${lspState} 37 |
38 | ` 39 | ) 40 | return text; 41 | } 42 | 43 | function computeText(): string { 44 | const clientState = getLspClient()?.state ?? State.Stopped; 45 | 46 | switch (clientState) { 47 | case State.Running: 48 | return `\$(check) ${TITLE}`; 49 | case State.Starting: 50 | return `\$(sync) ${TITLE}`; 51 | default: 52 | return `\$(stop) ${TITLE}`; 53 | } 54 | } 55 | 56 | function getLspClientStatus(): string { 57 | const clientState = getLspClient()?.state ?? State.Stopped; 58 | const restartButton = `$(sync)` 59 | switch (clientState) { 60 | case State.Running: 61 | return `\$(check) ${LSP_TITLE}: Running  ${restartButton}`; 62 | case State.Starting: 63 | return `\$(sync) ${LSP_TITLE}: Starting`; 64 | default: 65 | return `\$(stop) ${LSP_TITLE}: Stopped  ${restartButton}`; 66 | } 67 | } -------------------------------------------------------------------------------- /kotlin-vscode/client/testSources/tokenization/sample.kt: -------------------------------------------------------------------------------- 1 | // SYNTAX TEST "source.kotlin" "sample testcase" 2 | 3 | package example.kotlin.highlighting 4 | 5 | import kotlin.math.PI 6 | 7 | inline fun getIntValue(): Int = 42 8 | 9 | abstract class Shape(val name: String) { 10 | abstract val area: Double 11 | 12 | open fun displayInfo() { 13 | println("Shape: $name") 14 | } 15 | 16 | protected open val protectedProperty: String = "Protected" 17 | } 18 | 19 | data class Circle(val radius: Double) : Shape("Circle") { 20 | override val area: Double 21 | get() = PI * radius * radius 22 | 23 | override fun displayInfo() { 24 | super.displayInfo() 25 | println("Radius: $radius, Area: $area") 26 | } 27 | } 28 | 29 | interface Printable { 30 | fun printDetails() { 31 | println("Printing details...") 32 | } 33 | } 34 | 35 | object Singleton : Printable { 36 | override fun printDetails() { 37 | println("This is a Singleton object.") 38 | } 39 | 40 | private val privateProperty: String = "Private" 41 | internal val internalProperty: String = "Internal" 42 | } 43 | 44 | enum class Direction { 45 | NORTH, SOUTH, EAST, WEST 46 | } 47 | 48 | sealed class Result { 49 | data class Success(val message: String) : Result() 50 | data class Error(val errorMessage: String) : Result() 51 | object Loading : Result() 52 | } 53 | 54 | fun main() { 55 | val number: Int = 10 56 | var name: String = "Kotlin" 57 | val doubleValue: Double = 3.14 58 | val binaryNumber = 0b1010 59 | val hexNumber = 0x1A3F 60 | val floatNumber = 3.14e-2 61 | 62 | val nullableString: String? = null 63 | val nonNullableString: String = "Hello" 64 | 65 | val publicProperty: String = "Public" 66 | 67 | println("The number is $number") 68 | 69 | val circle = Circle(5.0) 70 | circle.displayInfo() 71 | 72 | Singleton.printDetails() 73 | 74 | val direction = Direction.NORTH 75 | println("Direction is $direction") 76 | val result: Result = Result.Success("Operation successful") 77 | when (result) { 78 | is Result.Success -> println(result.message) 79 | is Result.Error -> println(result.errorMessage) 80 | Result.Loading -> println("Loading...") 81 | } 82 | } 83 | 84 | /** 85 | * This is a test function 86 | */ 87 | fun testFunction(): Int { 88 | return 42 89 | } 90 | 91 | fun controlFlowTests() { 92 | if (immutableValue.isNotEmpty()) { 93 | println("Not empty") 94 | } else { 95 | println("Empty") 96 | } 97 | 98 | for (i in 1..10) { 99 | println(i) 100 | } 101 | } 102 | 103 | annotation class CustomAnnotation 104 | 105 | @CustomAnnotation 106 | class AnnotatedClass 107 | val escapedString = "Line break: \n Tab: \t Unicode: \u1234" 108 | val tripleQuotedString = """This is a 109 | multi-line string""" 110 | 111 | fun operatorsTest(a: Int, b: Int): Int { 112 | return a + b * (a - b) / a % b 113 | } 114 | 115 | fun functionWithVarargs(vararg numbers: Int) { 116 | for (num in numbers) { 117 | println(num) 118 | } 119 | } 120 | 121 | suspend fun fetchData(): String { 122 | return "Data fetched" 123 | } 124 | 125 | val generic: List = listOf(1, 2, 3) 126 | -------------------------------------------------------------------------------- /kotlin-vscode/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es2020", 5 | "strict": true, 6 | "lib": [ 7 | "es2020" 8 | ], 9 | "outDir": "out", 10 | "rootDir": "src", 11 | "sourceMap": true, 12 | "composite": true, 13 | "tsBuildInfoFile": "out/tsconfig.tsbuildinfo" 14 | }, 15 | "include": [ 16 | "src", "test" 17 | ], 18 | "exclude": [ 19 | "node_modules", 20 | ".vscode-test" 21 | ] 22 | } -------------------------------------------------------------------------------- /kotlin-vscode/icons/kotlin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/kotlin-vscode/icons/kotlin.png -------------------------------------------------------------------------------- /kotlin-vscode/language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "//", 4 | "blockComment": [ "/*", "*/" ] 5 | }, 6 | "brackets": [ 7 | ["{", "}"], 8 | ["[", "]"], 9 | ["(", ")"], 10 | ["<", ">"] 11 | ], 12 | "autoClosingPairs": [ 13 | ["{", "}"], 14 | ["[", "]"], 15 | ["(", ")"], 16 | ["\"", "\""], 17 | ["'", "'"], 18 | ["<", ">"], 19 | ["`", "`"] 20 | ], 21 | "surroundingPairs": [ 22 | ["{", "}"], 23 | ["[", "]"], 24 | ["(", ")"], 25 | ["\"", "\""], 26 | ["'", "'"], 27 | ["<", ">"], 28 | ["`", "`"] 29 | ] 30 | } -------------------------------------------------------------------------------- /kotlin-vscode/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kotlin", 3 | "version": "0.0.1", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "kotlin", 9 | "version": "0.0.1", 10 | "hasInstallScript": true, 11 | "license": "Apache-2.0", 12 | "dependencies": { 13 | "compile": "^0.0.2", 14 | "run": "^1.5.0" 15 | }, 16 | "devDependencies": { 17 | "typescript": "^5.7.2" 18 | }, 19 | "engines": { 20 | "vscode": "^1.96.0" 21 | } 22 | }, 23 | "node_modules/balanced-match": { 24 | "version": "1.0.2", 25 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 26 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 27 | "license": "MIT" 28 | }, 29 | "node_modules/brace-expansion": { 30 | "version": "2.0.1", 31 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 32 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 33 | "license": "MIT", 34 | "dependencies": { 35 | "balanced-match": "^1.0.0" 36 | } 37 | }, 38 | "node_modules/compile": { 39 | "version": "0.0.2", 40 | "resolved": "https://registry.npmjs.org/compile/-/compile-0.0.2.tgz", 41 | "integrity": "sha512-q5Ql5vqorGj+Z5RIH4hhjbjTYu9ToomfRjPWjEybJ3eT8dE6cnnmkrxZvsEMiMS55Y9pxRP9AVHUhQyen1A7Yg==", 42 | "license": "MIT", 43 | "engines": { 44 | "node": "0.x" 45 | } 46 | }, 47 | "node_modules/minimatch": { 48 | "version": "10.0.1", 49 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", 50 | "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", 51 | "license": "ISC", 52 | "dependencies": { 53 | "brace-expansion": "^2.0.1" 54 | }, 55 | "engines": { 56 | "node": "20 || >=22" 57 | }, 58 | "funding": { 59 | "url": "https://github.com/sponsors/isaacs" 60 | } 61 | }, 62 | "node_modules/run": { 63 | "version": "1.5.0", 64 | "resolved": "https://registry.npmjs.org/run/-/run-1.5.0.tgz", 65 | "integrity": "sha512-CBPzeX6JQZUdhZpSFyNt2vUk44ivKMWZYCNBYoZYEE46mL9nf6WyMP3320WnzIrJuo89+njiUvlo83jUEXjXLg==", 66 | "dependencies": { 67 | "minimatch": "*" 68 | }, 69 | "bin": { 70 | "runjs": "cli.js" 71 | }, 72 | "engines": { 73 | "node": ">=v0.9.0" 74 | } 75 | }, 76 | "node_modules/typescript": { 77 | "version": "5.8.2", 78 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", 79 | "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", 80 | "dev": true, 81 | "license": "Apache-2.0", 82 | "bin": { 83 | "tsc": "bin/tsc", 84 | "tsserver": "bin/tsserver" 85 | }, 86 | "engines": { 87 | "node": ">=14.17" 88 | } 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /kotlin-vscode/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kotlin", 3 | "displayName": "Kotlin by JetBrains", 4 | "description": "Language Support for Kotlin by JetBrains", 5 | "author": "JetBrains", 6 | "publisher": "JetBrains", 7 | "bugs": "https://github.com/Kotlin/kotlin-lsp", 8 | "icon": "icons/kotlin.png", 9 | "version": "0.0.1", 10 | "license": "Apache-2.0", 11 | "repository": { 12 | "url": "https://github.com/Kotlin/kotlin-lsp", 13 | "directory": "kotlin-vscode" 14 | }, 15 | "engines": { 16 | "vscode": "^1.96.0" 17 | }, 18 | "categories": [ 19 | "Programming Languages" 20 | ], 21 | "main": "./client/out/extension", 22 | "activationEvents": [ 23 | "onLanguage:kotlin", 24 | "onCommand:jetbrains.activateLsp" 25 | ], 26 | "contributes": { 27 | "languages": [ 28 | { 29 | "id": "kotlin", 30 | "aliases": [ 31 | "Kotlin", 32 | "kotlin" 33 | ], 34 | "extensions": [ 35 | ".kt" 36 | ], 37 | "configuration": "./language-configuration.json" 38 | } 39 | ], 40 | "grammars": [ 41 | { 42 | "language": "kotlin", 43 | "scopeName": "source.kotlin", 44 | "path": "./syntaxes/kotlin.tmLanguage.json" 45 | } 46 | ], 47 | "configuration":{ 48 | "title": "Kotlin", 49 | "properties": { 50 | "kotlinLSP.dev.serverPort": { 51 | "type": "number", 52 | "default": -1, 53 | "description": "Port for the locally started Kotlin Language Server to listen on. -1 to start the bundled LSP" 54 | }, 55 | "kotlinLSP.jrePathToRunLsp": { 56 | "type": "string", 57 | "default": null, 58 | "description": "A path to the JRE that will be used to run the LSP. It should be at least version 17. If not specified, default java version will be used" 59 | } 60 | } 61 | }, 62 | "commands": [ 63 | { 64 | "command": "jetbrains.exportWorkspaceToJson", 65 | "category": "Workspaces", 66 | "title": "Export workspace structure to JSON" 67 | }, 68 | { 69 | "command": "jetbrains.kotlin.restartLsp", 70 | "category": "Kotlin", 71 | "title": "Restart LSP server" 72 | } 73 | ] 74 | }, 75 | "devDependencies": { 76 | "typescript": "^5.7.2" 77 | }, 78 | "dependencies": { 79 | "compile": "^0.0.2", 80 | "run": "^1.5.0" 81 | }, 82 | "scripts": { 83 | "vscode:prepublish": "npm install && npm run compile && npm run unpack-server", 84 | "compile": "tsc -b", 85 | "watch": "tsc -b -w", 86 | "unpack-server": "rm -rf server/extracted && mkdir -p server/extracted && unzip -o $LSP_ZIP_PATH -d server/extracted", 87 | "postinstall": "cd client && npm install" 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /kotlin-vscode/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "strict": true, 5 | "target": "es2020", 6 | "lib": [ 7 | "es2020" 8 | ], 9 | "outDir": "out", 10 | "rootDir": "src", 11 | "sourceMap": true, 12 | "tsBuildInfoFile": "out/tsconfig.tsbuildinfo" 13 | }, 14 | "exclude": [ 15 | "node_modules", 16 | ".vscode-test" 17 | ], 18 | "references": [ 19 | { 20 | "path": "./client" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /scripts/lsp-kotlin-emacs.el: -------------------------------------------------------------------------------- 1 | (defun kotlin-lsp-server-start-fun (port) 2 | (list "kotlin-lsp.sh" "--port" (number-to-string port))) 3 | (with-eval-after-load 'lsp-mode 4 | (add-to-list 'lsp-language-id-configuration 5 | '(kotlin-mode . "kotlin")) 6 | 7 | (lsp-register-client 8 | (make-lsp-client 9 | :new-connection (lsp-tcp-connection 'kotlin-lsp-server-start-fun) 10 | :activation-fn (lsp-activate-on "kotlin") 11 | :major-modes '(kotlin-mode) 12 | :priority -1 13 | :server-id 'kotlin-jb-lsp 14 | ) 15 | ) 16 | ) -------------------------------------------------------------------------------- /scripts/neovim.md: -------------------------------------------------------------------------------- 1 | # neovim setup 2 | 3 | ## stdio way 4 | 5 | 1. Ensure socat and netcat are installed 6 | 7 | 2. Ensure `kotlin-lsp.sh` is executable 8 | 9 | ```sh 10 | chmod +x $KOTLIN_LSP_DIR/kotlin-lsp.sh 11 | ``` 12 | 13 | 3. Create a symlink inside your `PATH` to `kotlin-lsp.sh` script, e.g.: 14 | 15 | ```sh 16 | ln -s $KOTLIN_LSP_DIR/kotlin-lsp.sh $HOME/.local/bin/kotlin-ls 17 | ``` 18 | 19 | 4. Configure [nvim.lsp](https://neovim.io/doc/user/lsp.html) e.g: 20 | ```lua 21 | { 22 | cmd = { "kotlin-ls", "--stdio" }, 23 | single_file_support = true, 24 | filetypes = { "kotlin" }, 25 | root_markers = { "build.gradle", "build.gradle.kts", "pom.xml" }, 26 | } 27 | ``` 28 | 29 | ## tcp way 30 | 31 | Requires manual launch of language server 32 | 33 | 1. launch language server with `kotlin-lsp.sh` script 34 | 35 | 2. Configure [nvim.lsp](https://neovim.io/doc/user/lsp.html) e.g: 36 | ```lua 37 | { 38 | cmd = vim.lsp.rpc.connect('127.0.0.1', tonumber(9999)) 39 | single_file_support = true, 40 | filetypes = { "kotlin" }, 41 | root_markers = { "build.gradle", "build.gradle.kts", "pom.xml" }, 42 | } 43 | ``` 44 | 45 | -------------------------------------------------------------------------------- /scripts/zed-settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // Note: you'll need to install "Kotlin" extension via Zed extensions: https://github.com/zed-extensions/kotlin 3 | // See the README.md file for more information on how to configure kotlin-lsp in Zed 4 | // Also note: diagnostics do not work because they are pull-based in our implementation, but the editor expects them to be push-based 5 | // Things like navigation, completion, find references and code actions like organize imports do. 6 | "languages": { 7 | "Kotlin": { 8 | "language_servers": [ 9 | "kotlin-lsp" 10 | ] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /workspace-import/BUILD.bazel: -------------------------------------------------------------------------------- 1 | ### auto-generated section `build language-server.project-import` start 2 | load("@community//build:compiler-options.bzl", "create_kotlinc_options") 3 | load("@rules_jvm//:jvm.bzl", "jvm_library") 4 | 5 | create_kotlinc_options( 6 | name = "custom", 7 | context_receivers = True 8 | ) 9 | 10 | jvm_library( 11 | name = "language-server-project-import", 12 | module_name = "language-server.project-import", 13 | visibility = ["//visibility:public"], 14 | srcs = glob(["gen/**/*.kt", "gen/**/*.java", "src/**/*.kt", "src/**/*.java"], allow_empty = True), 15 | kotlinc_opts = ":custom", 16 | deps = [ 17 | "@lib//:gradle", 18 | "@lib//:kotlin-stdlib", 19 | "@community//platform/workspace/jps", 20 | "@community//platform/workspace/storage", 21 | "//language-server/community/api.core", 22 | "@community//plugins/gradle", 23 | "@community//platform/util", 24 | "@lib//:kotlinx-serialization-core", 25 | "@lib//:kotlinx-serialization-json", 26 | "@community//java/java-impl:impl", 27 | "@community//java/openapi:java", 28 | "@community//plugins/kotlin/base/facet", 29 | "@community//jps/model-api:model", 30 | "@lib//:kotlinc-kotlin-jps-common", 31 | "@lib//:kotlinc-kotlin-jps-plugin-classpath", 32 | ] 33 | ) 34 | ### auto-generated section `build language-server.project-import` end -------------------------------------------------------------------------------- /workspace-import/gen/com/jetbrains/ls/imports/api/impl/MetadataStorageImpl.kt: -------------------------------------------------------------------------------- 1 | package com.jetbrains.ls.imports.api.impl 2 | 3 | import com.intellij.platform.workspace.storage.WorkspaceEntityInternalApi 4 | import com.intellij.platform.workspace.storage.metadata.impl.MetadataStorageBase 5 | import com.intellij.platform.workspace.storage.metadata.model.FinalClassMetadata 6 | import com.intellij.platform.workspace.storage.metadata.model.OwnPropertyMetadata 7 | import com.intellij.platform.workspace.storage.metadata.model.StorageTypeMetadata 8 | import com.intellij.platform.workspace.storage.metadata.model.ValueTypeMetadata 9 | 10 | @OptIn(WorkspaceEntityInternalApi::class) 11 | internal object MetadataStorageImpl: MetadataStorageBase() { 12 | override fun initializeMetadata() { 13 | 14 | var typeMetadata: StorageTypeMetadata 15 | 16 | typeMetadata = FinalClassMetadata.ClassMetadata(fqName = "com.jetbrains.ls.imports.api.WorkspaceEntitySource", properties = listOf(OwnPropertyMetadata(isComputable = false, isKey = false, isOpen = false, name = "virtualFileUrl", valueType = ValueTypeMetadata.SimpleType.CustomType(isNullable = false, typeMetadata = FinalClassMetadata.KnownClass(fqName = "com.intellij.platform.workspace.storage.url.VirtualFileUrl")), withDefault = false)), supertypes = listOf("com.intellij.platform.workspace.storage.EntitySource")) 17 | 18 | addMetadata(typeMetadata) 19 | } 20 | 21 | override fun initializeMetadataHash() { 22 | addMetadataHash(typeFqn = "com.intellij.platform.workspace.storage.EntitySource", metadataHash = -1916480691) 23 | addMetadataHash(typeFqn = "com.jetbrains.ls.imports.api.WorkspaceEntitySource", metadataHash = 20366397) 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /workspace-import/language-server.project-import.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | $KOTLIN_BUNDLED$/lib/kotlinx-serialization-compiler-plugin.jar 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /workspace-import/src/com/jetbrains/ls/imports/api/WorkspaceEntitySource.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.imports.api 3 | 4 | import com.intellij.platform.workspace.storage.EntitySource 5 | import com.intellij.platform.workspace.storage.url.VirtualFileUrl 6 | 7 | data class WorkspaceEntitySource(override val virtualFileUrl: VirtualFileUrl): EntitySource 8 | -------------------------------------------------------------------------------- /workspace-import/src/com/jetbrains/ls/imports/api/WorkspaceImporter.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.imports.api 3 | 4 | import com.intellij.platform.workspace.storage.MutableEntityStorage 5 | import com.intellij.platform.workspace.storage.url.VirtualFileUrlManager 6 | import java.nio.file.Path 7 | 8 | interface WorkspaceImporter { 9 | suspend fun tryImportWorkspace(projectDirectory: Path, virtualFileUrlManager: VirtualFileUrlManager, onUnresolvedDependency: (String) -> Unit): MutableEntityStorage? { 10 | if (!isApplicableDirectory(projectDirectory)) return null 11 | return importWorkspace(projectDirectory, virtualFileUrlManager, onUnresolvedDependency) 12 | } 13 | 14 | suspend fun importWorkspace(projectDirectory: Path, virtualFileUrlManager: VirtualFileUrlManager, onUnresolvedDependency: (String) -> Unit): MutableEntityStorage 15 | fun isApplicableDirectory(projectDirectory: Path): Boolean 16 | } 17 | 18 | class WorkspaceImportException(displayMessage: String, val logMessage: String?): Exception(displayMessage) -------------------------------------------------------------------------------- /workspace-import/src/com/jetbrains/ls/imports/json/JsonWorkspaceImporter.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.imports.json 3 | 4 | import com.intellij.platform.workspace.storage.MutableEntityStorage 5 | import com.intellij.platform.workspace.storage.impl.url.toVirtualFileUrl 6 | import com.intellij.platform.workspace.storage.url.VirtualFileUrlManager 7 | import com.jetbrains.ls.imports.api.WorkspaceEntitySource 8 | import com.jetbrains.ls.imports.api.WorkspaceImportException 9 | import com.jetbrains.ls.imports.api.WorkspaceImporter 10 | import kotlinx.serialization.SerializationException 11 | import kotlinx.serialization.json.Json 12 | import java.nio.file.Path 13 | import kotlin.io.path.div 14 | import kotlin.io.path.exists 15 | import kotlin.io.path.notExists 16 | 17 | object JsonWorkspaceImporter : WorkspaceImporter { 18 | override suspend fun importWorkspace( 19 | projectDirectory: Path, 20 | virtualFileUrlManager: VirtualFileUrlManager, 21 | onUnresolvedDependency: (String) -> Unit 22 | ): MutableEntityStorage { 23 | try { 24 | val content = (projectDirectory / "workspace.json").toFile().readText() 25 | val workspaceData = Json.decodeFromString(content) 26 | workspaceData.modules.forEach { module -> 27 | module.dependencies 28 | .filterIsInstance() 29 | .filter { it.name != "JDK" } 30 | .filter { dependency -> workspaceData.libraries.none { it.name == dependency.name } } 31 | .forEach { onUnresolvedDependency(it.name.removePrefix("Gradle: ")) } 32 | } 33 | workspaceData.libraries.forEach { library -> 34 | if (library.roots.any { toAbsolutePath(it.path, projectDirectory).notExists()}) { 35 | onUnresolvedDependency(library.name.removePrefix("Gradle: ")) 36 | } 37 | } 38 | return workspaceModel( 39 | workspaceData, 40 | projectDirectory, 41 | WorkspaceEntitySource(projectDirectory.toVirtualFileUrl(virtualFileUrlManager)), 42 | virtualFileUrlManager 43 | ) 44 | } catch (e: SerializationException) { 45 | throw WorkspaceImportException( 46 | "Error parsing workspace.json", 47 | "Error parsing workspace.json:\n ${e.message ?: e.stackTraceToString()}" 48 | ) 49 | } catch (e: Exception) { 50 | throw e 51 | } 52 | } 53 | 54 | override fun isApplicableDirectory(projectDirectory: Path): Boolean = 55 | (projectDirectory / "workspace.json").exists() 56 | 57 | } -------------------------------------------------------------------------------- /workspace-import/src/com/jetbrains/ls/imports/json/XmlUtils.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.imports.json 3 | 4 | import org.w3c.dom.Document 5 | import org.w3c.dom.Element 6 | import org.w3c.dom.Node 7 | import java.io.StringReader 8 | import javax.xml.parsers.DocumentBuilderFactory 9 | import org.xml.sax.InputSource 10 | import java.io.StringWriter 11 | import javax.xml.transform.OutputKeys 12 | import javax.xml.transform.TransformerFactory 13 | import javax.xml.transform.dom.DOMSource 14 | import javax.xml.transform.stream.StreamResult 15 | 16 | internal fun parseXml(xmlString: String): XmlElement { 17 | val factory = DocumentBuilderFactory.newInstance() 18 | val builder = factory.newDocumentBuilder() 19 | val inputSource = InputSource(StringReader(xmlString)) 20 | val document = builder.parse(inputSource) 21 | val root = document.documentElement 22 | return parseElement(root, xmlString) 23 | } 24 | 25 | private fun parseElement(element: Element, xmlString: String): XmlElement { 26 | val attributeNodes = mutableListOf() 27 | for (i in 0 until element.attributes.length) { 28 | val attr = element.attributes.item(i) 29 | attributeNodes.add(attr) 30 | } 31 | 32 | // An attempt to preserve the original attribute order for better readability. Not very reliable, but works in most cases. 33 | attributeNodes.sortBy { xmlString.indexOf(it.nodeName) } 34 | 35 | val children = mutableListOf() 36 | val childNodes = element.childNodes 37 | for (i in 0 until childNodes.length) { 38 | val childNode = childNodes.item(i) 39 | if (childNode.nodeType == Node.ELEMENT_NODE) { 40 | children.add(parseElement(childNode as Element, xmlString)) 41 | } 42 | } 43 | 44 | val text = element.textContent.trim().takeIf { it.isNotEmpty() } 45 | 46 | return XmlElement( 47 | tag = element.tagName, 48 | attributes = attributeNodes.associate { it.nodeName to it.nodeValue }, 49 | children = children, 50 | text = text 51 | ) 52 | } 53 | 54 | 55 | internal fun toXml(xmlElement: XmlElement): String { 56 | val documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder() 57 | val document = documentBuilder.newDocument() 58 | val rootElement = buildElement(document, xmlElement) 59 | document.appendChild(rootElement) 60 | val writer = StringWriter() 61 | val transformer = TransformerFactory.newInstance().newTransformer() 62 | transformer.setOutputProperty(OutputKeys.INDENT, "yes") 63 | transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4") 64 | transformer.transform(DOMSource(document), StreamResult(writer)) 65 | return writer.toString() 66 | } 67 | 68 | private fun buildElement(document: Document, xmlElement: XmlElement): Element { 69 | val element = document.createElement(xmlElement.tag) 70 | xmlElement.attributes.forEach { (key, value) -> 71 | element.setAttribute(key, value) 72 | } 73 | xmlElement.children.forEach { child -> 74 | val childElement = buildElement(document, child) 75 | element.appendChild(childElement) 76 | } 77 | xmlElement.text?.let { 78 | element.appendChild(document.createTextNode(it)) 79 | } 80 | return element 81 | } 82 | -------------------------------------------------------------------------------- /workspace-import/src/com/jetbrains/ls/imports/utils/uri.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package com.jetbrains.ls.imports.utils 3 | 4 | import com.intellij.platform.workspace.storage.url.VirtualFileUrl 5 | import com.intellij.platform.workspace.storage.url.VirtualFileUrlManager 6 | import com.jetbrains.ls.api.core.util.UriConverter 7 | import java.nio.file.Path 8 | import kotlin.io.path.absolutePathString 9 | 10 | internal fun String.toIntellijUri(virtualFileUrlManager: VirtualFileUrlManager): VirtualFileUrl = 11 | virtualFileUrlManager.getOrCreateFromUrl(asIntelliJUriString()) 12 | 13 | internal fun Path.toIntellijUri(virtualFileUrlManager: VirtualFileUrlManager): VirtualFileUrl = 14 | absolutePathString().toIntellijUri(virtualFileUrlManager) 15 | 16 | private fun String.asIntelliJUriString(): String { 17 | val scheme = substringBefore("://", missingDelimiterValue = "file") 18 | val path = substringAfter("://") 19 | val uri = "$scheme://$path" 20 | val lspUri = UriConverter.intellijUriToLspUri(uri) 21 | return UriConverter.lspUriToIntellijUri(lspUri)!! 22 | } 23 | 24 | -------------------------------------------------------------------------------- /workspace-import/test/BUILD.bazel: -------------------------------------------------------------------------------- 1 | ### auto-generated section `build language-server.project-import.test` start 2 | load("@community//build:compiler-options.bzl", "create_kotlinc_options") 3 | load("@rules_java//java:defs.bzl", "java_library") 4 | load("@rules_jvm//:jvm.bzl", "jvm_library", "jvm_test") 5 | 6 | create_kotlinc_options( 7 | name = "custom", 8 | context_receivers = True 9 | ) 10 | 11 | java_library( 12 | name = "test", 13 | visibility = ["//visibility:public"] 14 | ) 15 | 16 | jvm_library( 17 | name = "test_test_lib", 18 | visibility = ["//visibility:public"], 19 | srcs = glob(["test/**/*.kt", "test/**/*.java"], allow_empty = True), 20 | kotlinc_opts = ":custom", 21 | deps = [ 22 | "@lib//:kotlin-stdlib", 23 | "@lib//:junit5", 24 | "@lib//:gson", 25 | "@community//platform/workspace/storage", 26 | "//language-server/test-api:test-api_test_lib", 27 | "@community//platform/projectModel-impl", 28 | "@community//platform/util", 29 | "//language-server/community/workspace-import:language-server-project-import", 30 | "@community//platform/workspace/jps", 31 | "//language-server/api.impl.analyzer", 32 | "//language-server/community/api.core", 33 | "//language-server/community/api.core:api.core_test_lib", 34 | "@community//plugins/kotlin/base/facet", 35 | "@lib//:kotlinx-serialization-json", 36 | "@lib//:kotlinx-serialization-core", 37 | "@community//platform/core-impl", 38 | ] 39 | ) 40 | 41 | jvm_test( 42 | name = "test_test", 43 | runtime_deps = [":test_test_lib"] 44 | ) 45 | ### auto-generated section `build language-server.project-import.test` end -------------------------------------------------------------------------------- /workspace-import/test/language-server.project-import.test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/.gitignore: -------------------------------------------------------------------------------- 1 | **/.gradle 2 | **/build -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | } 4 | 5 | dependencies { 6 | implementation(project(":lib")) 7 | implementation(kotlin("reflect")) 8 | } -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/app/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/app/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/app/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/app/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/app/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/app/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/app/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/app/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/app/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/app/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/app/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/app/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") version "1.9.10" 3 | } 4 | 5 | subprojects { 6 | repositories { 7 | mavenCentral() 8 | } 9 | } -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/lib/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | } 4 | 5 | dependencies { 6 | implementation(kotlin("stdlib")) 7 | } 8 | 9 | // Custom source sets 10 | sourceSets { 11 | create("integrationTest") { 12 | kotlin.srcDirs("src/integrationTest/kotlin") 13 | resources.srcDirs("src/integrationTest/resources") 14 | compileClasspath += sourceSets["main"].output 15 | runtimeClasspath += sourceSets["main"].output 16 | } 17 | } 18 | 19 | tasks.register("integrationTest") { 20 | testClassesDirs = sourceSets["integrationTest"].output.classesDirs 21 | classpath = sourceSets["integrationTest"].runtimeClasspath 22 | } -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/lib/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/lib/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/lib/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/lib/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/lib/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/lib/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/lib/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/lib/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/lib/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/lib/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/lib/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/lib/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "multi-project-source-sets" 2 | 3 | include("lib") 4 | include("app") -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/CustomSourceSets/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/CustomSourceSets/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/Dependencies/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") version "1.9.10" 3 | application // Enables creating a runnable application 4 | } 5 | 6 | repositories { 7 | // Maven Central (default source for most libraries) 8 | mavenCentral() 9 | 10 | // Google Maven repository (e.g., for Android-related or other Google-provided libraries) 11 | google() 12 | 13 | // JFrog Bintray (common hosting for projects like JCenter-based libraries) 14 | maven { 15 | url = uri("https://repo.gradle.org/gradle/libs-releases") // Example for Gradle-provided dependencies 16 | } 17 | 18 | // Spring Plugins repository for Spring-related dependencies 19 | maven { 20 | url = uri("https://repo.spring.io/plugins-release") 21 | } 22 | 23 | // JitPack repository for GitHub-hosted dependencies 24 | maven { 25 | url = uri("https://jitpack.io") 26 | } 27 | } 28 | 29 | dependencies { 30 | // Kotlin Standard Library 31 | implementation(kotlin("stdlib")) 32 | 33 | // Coroutines for asynchronous programming 34 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1") 35 | 36 | // Moshi for JSON serialization/deserialization 37 | implementation("com.squareup.moshi:moshi:1.15.0") 38 | 39 | // Apache Commons Lang - popular utility library 40 | implementation("org.apache.commons:commons-lang3:3.12.0") 41 | 42 | // Guava (core libraries for Java by Google) 43 | implementation("com.google.guava:guava:32.1.1-jre") 44 | 45 | // Logback (logging framework) 46 | implementation("ch.qos.logback:logback-classic:1.4.11") 47 | 48 | // Custom JitPack dependency hosted on GitHub 49 | implementation("com.github.User:Repo:Tag") // Replace "User", "Repo", and "Tag" with actual GitHub repo values 50 | 51 | // Compile-only dependencies (e.g., for annotation processors) 52 | compileOnly("org.projectlombok:lombok:1.18.28") 53 | 54 | // Annotation processor 55 | annotationProcessor("org.projectlombok:lombok:1.18.28") 56 | 57 | // Runtime-only dependencies (libraries needed only at runtime) 58 | runtimeOnly("mysql:mysql-connector-java:8.0.34") // MySQL connector for database operations 59 | 60 | // Testing dependencies 61 | testImplementation(kotlin("test")) // Kotlin test framework 62 | testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") // JUnit 5 for testing 63 | testImplementation("io.mockk:mockk:1.13.7") // Mocking library for Kotlin 64 | testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.10.0") 65 | } 66 | 67 | tasks.test { 68 | useJUnitPlatform() // Enable JUnit 5 for testing. 69 | } 70 | 71 | application { 72 | // Define the main class for the runnable application 73 | mainClass.set("com.example.kotlin.MainKt") 74 | } -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/Dependencies/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "kotlin-dependency-example" -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/Dependencies/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/Dependencies/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/Dependencies/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/Dependencies/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/Dependencies/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/Dependencies/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/Dependencies/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/Dependencies/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/Dependencies/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/Dependencies/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/Dependencies/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/Dependencies/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/Empty/.gitkeep: -------------------------------------------------------------------------------- 1 | There's no Gradle project in this directory -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/api/build.gradle: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | dependencies { 3 | implementation project(':core') 4 | } 5 | -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/api/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/api/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/api/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/api/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/api/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/api/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/api/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/api/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/api/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/api/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/api/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/api/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/build.gradle: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | plugins { 3 | id 'org.jetbrains.kotlin.jvm' version '1.9.10' apply false 4 | } 5 | 6 | subprojects { 7 | repositories { 8 | mavenCentral() 9 | } 10 | 11 | apply plugin: 'org.jetbrains.kotlin.jvm' 12 | 13 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) { 14 | kotlinOptions { 15 | jvmTarget = '17' 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/core/build.gradle: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | dependencies { 3 | implementation "org.jetbrains.kotlin:kotlin-stdlib" 4 | } 5 | -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/core/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/core/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/core/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/core/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/core/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/core/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/core/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/core/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/core/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/core/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/core/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/core/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/service/build.gradle: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | dependencies { 3 | implementation project(':api') 4 | implementation "org.jetbrains.kotlin:kotlin-reflect" 5 | } -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/service/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/service/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/service/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/service/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/service/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/service/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/service/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/service/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/service/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/service/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/service/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/service/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/settings.gradle: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | rootProject.name = 'multi-project-example' 3 | 4 | include 'core', 'api', 'service' -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectGroovyDSL/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectGroovyDSL/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation(project(":core")) 3 | } 4 | -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/api/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/api/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/api/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/api/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/api/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/api/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/api/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/api/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/api/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/api/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/api/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/api/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") version "1.9.10" 3 | } 4 | 5 | subprojects { 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | plugins.apply("org.jetbrains.kotlin.jvm") 11 | 12 | tasks.withType { 13 | kotlinOptions.jvmTarget = "17" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/core/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation(kotlin("stdlib")) 3 | } -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/core/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/core/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/core/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/core/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/core/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/core/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/core/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/core/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/core/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/core/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/core/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/core/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/service/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation(project(":api")) 3 | implementation(kotlin("reflect")) 4 | } 5 | -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/service/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/service/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/service/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/service/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/service/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/service/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/service/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/service/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/service/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/service/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/service/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/service/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "multi-project-example" 2 | 3 | include("core") 4 | include("api") 5 | include("service") 6 | -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/MultiProjectKotlinDSL/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/MultiProjectKotlinDSL/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/NonExistentDependency/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") version "1.9.10" 3 | application 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | google() 9 | } 10 | 11 | dependencies { 12 | implementation(kotlin("stdlib")) 13 | implementation("org.apache.commons:commons-lang3:3.12.0") 14 | implementation("com.example.nonexistent:nonexistent-library:1.0.0") 15 | } 16 | 17 | application { 18 | // Specify the main class of the application 19 | mainClass.set("com.example.MainKt") 20 | } -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/NonExistentDependency/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/NonExistentDependency/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/NonExistentDependency/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/NonExistentDependency/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/NonExistentDependency/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/NonExistentDependency/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/NonExistentDependency/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/NonExistentDependency/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/NonExistentDependency/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/NonExistentDependency/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/NonExistentDependency/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/NonExistentDependency/src/test/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/PetClinic/src/main/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/PetClinic/src/main/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/PetClinic/src/main/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/PetClinic/src/main/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/PetClinic/src/main/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/PetClinic/src/main/resources/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/PetClinic/src/test/java/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/PetClinic/src/test/java/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/PetClinic/src/test/kotlin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/PetClinic/src/test/kotlin/.gitkeep -------------------------------------------------------------------------------- /workspace-import/test/testData/gradle/PetClinic/src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kotlin/kotlin-lsp/7c57355182009640973ba6baf087e1eff86af608/workspace-import/test/testData/gradle/PetClinic/src/test/resources/.gitkeep --------------------------------------------------------------------------------