fwcd / kotlin-language-server

Kotlin code completion, diagnostics and more for any editor/IDE using the Language Server Protocol
MIT License
1.64k stars 206 forks source link

coc + kotlin-language-server + nvim building former Android Studio Project #284

Open kheaactua opened 3 years ago

kheaactua commented 3 years ago

(new to Kotlin, gradle, Android Apps, etc)

I got coc and kotlin-langugage-server working in Vim, but when I open my kotlin file every symbol is basically an error:

[kotlin MISSING_BUILT_IN_DECLARATION] [E] Cannot access built-in declaration 'kotlin.String'. Ensure that you have a dependency on the Kotlin standard library

This project works when I open it with Android Studio.

I've seen many similar reported issues, but the ones that were solved didn't look applicable.

My nvim is setup so that the work directory is the top of the git repo, my app is in client/, and it has a gradlew file. I've invoked ./gradlew androidDependencies which did something successfully.

I have log files, I'm not sure how to interpret the messages, though this appears pertinent:

/tmp/kotlin-daemon.2021-03-23.09-25-02-144.00.log

2021-03-23 09:25:05.441 [daemon] INFO: Message: logging: using Kotlin home directory <no_path>
2021-03-23 09:25:05.442 [daemon] INFO: Message: logging: scripting plugin will not be loaded: not all required jars are present in the classpath (missing files: [./kotlin-scripting-compiler.jar, ./kotlin-scripting-compiler-impl.jar, ./kotlinx-coroutines-core.jar, ./kotlin-scripting-common.jar, ./kotlin-scripting-jvm.jar, ./kotlin-scripting-js.jar, ./js.engines.jar])

I found kotlin-scripting-compiler.jar, and added its path to my CLASSPATH (tried PATH too) but this didn't help. I've even tried symlinking some of those files to a local path in an attempt to match the ./, all to no avail.

How can I get the kotlin-language-server to find my dependencies?

DonnieWest commented 3 years ago

@kheaactua do you happen to have a sample project this is happening on? It'd be useful to reason about

I've a personal project this just popped up on, and it seems like it's a kotlin-stdlib issue - almost like we're resolving the incorrect one. I think I have a fix but I want to make sure it's generalizable

kheaactua commented 3 years ago

I just created a brand new project in my repo, and I receive the same issue - basically an error on every line about missing symbols.

I've upgraded my setup to use neovim 0.5's LSP instead of coc, but it behaves the same. Specifically, in my init.vim I have:

if 1 == vim.fn.executable("kotlin-language-server") then
   require'lspconfig'.kotlin_language_server.setup{}
end

and I can see that the kotlin-language-server is running.

I'm seeing directories appear in /tmp, but now real logs. When I run commands like vim.lsp.diagnostic.show_line_diagnostics I see errors like:

Diagnostics:
1. Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6 Please specify proper '-jvm-target' option
2. Cannot access built-in declaration 'kotlin.Unit'. Ensure that you have a dependency on the Kotlin standard library

For vim.lsp.buf.declaration() I get:

RPC[Error] code_name = MethodNotFound, message = "method textDocument/declaration is not supported by any of the servers registered for the current buffer"

vim.lsp.bug.document_symbol() is working perfectly though.

I still suspect that it's CLASSPATH related as all my gradle stuff is in sub-directories rather than at the root. I have it like this because this is in a repo with other work.

DonnieWest commented 3 years ago

Gotcha. Yeah, looks like the same issue.

https://github.com/fwcd/kotlin-language-server/blob/58966bc18dd5bf82fdfcf7a2f44bab3622f6907a/shared/src/main/kotlin/org/javacs/kt/classpath/WithStdlibResolver.kt#L14-L42

I'm finding that if we modify the function here to:

        pathString.contains("kotlin-stdlib") && !pathString.contains("kotlin-stdlib-common") && pathString.contains("jdk")

It solves the issue for me. That's not a long term solution, but it might help you get patched up locally until a better solution is found. We're going to have to look at how we're resolving kotlin's stdlib and what exactly is causing the conflict here.

As a side note:

Your error 1. Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6 Please specify proper '-jvm-target' option is caused by Kotlin not using the right compiler. You can set it in vim like so:

nvim_lsp.kotlin_language_server.setup{
  settings = {
    kotlin = {
      compiler = {
        jvm = {
          target = "1.8";
        }
      };
    };
  }
}
kheaactua commented 3 years ago

awesome, I'll give that a try

kheaactua commented 3 years ago

@DonnieWest I think both changes (classpath and version version) are working! For example, now whe nmy cursor is over Collections.synchronizedList and I invoke vim.lsp.buf.hover(), I get the full definition:

fun <T : Any!> synchronizedList((Mutable)List<T!>!): (Mutable)List<T!>!

Thanks!