Ale: kotlinc doesn't show errors from stderr

Created on 17 Feb 2020  路  6Comments  路  Source: dense-analysis/ale

Information

VIM version

NVIM v0.4.3
Build type: Release

Operating System: Arch Linux, Linux Kernel 5.5.4

What went wrong

I was trying to use kotlinc to lint kotlin files and noticed it wasn't showing any lints, even from the following file hello.kt

fun main(args: Array<String>) {
    bad
}

Running essentially the same command listed in :ALEInfo /bin/zsh -c 'kotlinc "/home/lovecraft/hello.kt"' returns

/home/lovecraft/hello.kt:2:2: error: unresolved reference: bad
    bad
 ^

I think the problem stems from kotlinc outputting to stderr instead of stdout. My hacky way of testing this was to move kotlinc to kotlinc.orig and create a new kotlinc that redirects stderr to stdout like below

#!/usr/bin/bash

kotlinc.orig "$@" 2>&1

After that ALE correctly displays the error in hello.kt. Hopefully any of this is helpful, I really appreciate all the work the ALE maintainers have put into such a great plugin!

Reproducing the bug

  1. Install kotlinc
  2. Create a file with the same contents as hello.kt
  3. Run ALE and see there are no errors shown

:ALEInfo

 Current Filetype: kotlin
Available Linters: ['kotlinc', 'ktlint', 'languageserver']
  Enabled Linters: ['kotlinc', 'ktlint', 'languageserver']
 Suggested Fixers: 
  'remove_trailing_lines' - Remove all blank lines at the end of a file.
  'trim_whitespace' - Remove all trailing whitespace characters at the end of every line.
 Linter Variables:

let g:ale_kotlin_kotlinc_classpath = ''
let g:ale_kotlin_kotlinc_config_file = '.ale_kotlinc_config'
let g:ale_kotlin_kotlinc_enable_config = 0
let g:ale_kotlin_kotlinc_module_filename = 'module.xml'
let g:ale_kotlin_kotlinc_options = ''
let g:ale_kotlin_kotlinc_sourcepath = ''
let g:ale_kotlin_kotlinc_use_module_file = 0
let g:ale_kotlin_languageserver_executable = 'kotlin-language-server'
 Global Variables:

let g:ale_cache_executable_check_failures = v:null
let g:ale_change_sign_column_color = 0
let g:ale_command_wrapper = ''
let g:ale_completion_delay = v:null
let g:ale_completion_enabled = 0
let g:ale_completion_max_suggestions = v:null
let g:ale_echo_cursor = 1
let g:ale_echo_msg_error_str = 'E'
let g:ale_echo_msg_format = '[%linter%] [%severity%] %code:%%s'
let g:ale_echo_msg_info_str = 'Info'
let g:ale_echo_msg_warning_str = 'W'
let g:ale_enabled = 1
let g:ale_fix_on_save = 0
let g:ale_fixers = {'c': ['clang-format'], 'rust': ['rustfmt'], 'cpp': ['clang-format'], 'python': ['black']}
let g:ale_history_enabled = 1
let g:ale_history_log_output = 1
let g:ale_keep_list_window_open = 0
let g:ale_lint_delay = 1000
let g:ale_lint_on_enter = 1
let g:ale_lint_on_filetype_changed = 1
let g:ale_lint_on_insert_leave = 1
let g:ale_lint_on_save = 1
let g:ale_lint_on_text_changed = 'normal'
let g:ale_linter_aliases = {}
let g:ale_linters = {}
let g:ale_linters_explicit = 0
let g:ale_list_vertical = 0
let g:ale_list_window_size = 10
let g:ale_loclist_msg_format = '[%linter%] [%severity%] %code:%%s'
let g:ale_lsp_root = {}
let g:ale_max_buffer_history_size = 20
let g:ale_max_signs = -1
let g:ale_maximum_file_size = v:null
let g:ale_open_list = 0
let g:ale_pattern_options = v:null
let g:ale_pattern_options_enabled = v:null
let g:ale_set_balloons = 0
let g:ale_set_highlights = 1
let g:ale_set_loclist = 1
let g:ale_set_quickfix = 0
let g:ale_set_signs = 1
let g:ale_sign_column_always = 1
let g:ale_sign_error = 'XX'
let g:ale_sign_info = '!!'
let g:ale_sign_offset = 1000000
let g:ale_sign_style_error = 'XX'
let g:ale_sign_style_warning = '!!'
let g:ale_sign_warning = '!!'
let g:ale_sign_highlight_linenrs = 0
let g:ale_statusline_format = v:null
let g:ale_type_map = {}
let g:ale_use_global_executables = v:null
let g:ale_virtualtext_cursor = 0
let g:ale_warn_about_trailing_blank_lines = 1
let g:ale_warn_about_trailing_whitespace = 1
  Command History:

(executable check - success) kotlinc
(finished - exit code 1) ['/bin/zsh', '-c', 'kotlinc    ''/home/lovecraft/hello.kt''']

<<<NO OUTPUT RETURNED>>>

(executable check - failure) ktlint



bug help wanted

Most helpful comment

I am also dealing with the same problem. Big thanks for your suggestion, it seems like the code forgot to set output_stream when running the kotlinc linter (kotlinc.vim#L176).

'output_stream': 'stderr'

So I added one line only and it works.

call ale#linter#Define('kotlin', {
\   'name': 'kotlinc',
\   'executable': 'kotlinc',
\   'output_stream': 'stderr',           <------ add this line
\   'command': function('ale_linters#kotlin#kotlinc#RunWithImportPaths'),
\   'callback': 'ale_linters#kotlin#kotlinc#Handle',
\   'lint_file': 1,
\})

I also took a look to the test, but really I can't understand how to verify it :))) So I guess this is just a workaround.

All 6 comments

I am also dealing with the same problem. Big thanks for your suggestion, it seems like the code forgot to set output_stream when running the kotlinc linter (kotlinc.vim#L176).

'output_stream': 'stderr'

So I added one line only and it works.

call ale#linter#Define('kotlin', {
\   'name': 'kotlinc',
\   'executable': 'kotlinc',
\   'output_stream': 'stderr',           <------ add this line
\   'command': function('ale_linters#kotlin#kotlinc#RunWithImportPaths'),
\   'callback': 'ale_linters#kotlin#kotlinc#Handle',
\   'lint_file': 1,
\})

I also took a look to the test, but really I can't understand how to verify it :))) So I guess this is just a workaround.

the tests work based on an example output which is usually copy pasted from a terminal, so this change shouldn't affect tests. if you'd like to open a PR and test it out on some actual kotlin project that would be helpful.

I tested it on my kotlin + maven project, so far it works fine. So I make a pull request. Just a really small change :) Btw, my first ever pull request to a project that I really like :))

@ndtho8205 do you mind telling me which version of kotlinc you are using? trying this PR I cannot get ALE work with Kotlin/Native: 1.3.72. ALE fails with invalid argument: -cp.

Just want to verify if kotlinc outputs all important information only to stderr and not both stderr and stdout before merging this.

Sorry for my late response.

There are two types of Kotlin compiler: kotlinc-jvm and kotlinc-native (you can download them from here). The interface of those two are completely different. ALE linter currently only works on kotlinc-jvm which have argument -cp (--classpath) to include directories for searching java class files. Since you are using kotlinc-native, the ALE will fail.

$ kotlinc -help             #<--- the compiler that I installed (kotlin-compiler-1.3.72.zip)
Usage: kotlinc-jvm <options> <source files>
where possible options include:
  -classpath (-cp) <path>    List of directories and JAR/ZIP archives to search for user class files
  -d <directory|jar>         Destination for generated class files
  -include-runtime           Include Kotlin runtime into the resulting JAR
  -java-parameters           Generate metadata for Java 1.8 reflection on method parameters
  ...

$ ./kotlinc -help             #<--- file extracted from kotlin-native-linux-1.3.72.tar.gz
Usage: kotlinc-native <options> <source files>
where possible options include:
  -g                         Enable emitting debug information
  -enable-assertions (-ea)   Enable runtime assertions in generated code
  -friend-modules <path>     Paths to friend modules
  -generate-no-exit-test-runner (-trn)
  ...

Regarding the outputs of kotlinc, you can check its test cases from here and here. Based on these test cases, I think that all warning and errors will go to stderr.

I think you might need the output of ALEInfo so I include it here :D In this case, ALE with the pull request successfully captured the error output.

(executable check - success) kotlinc
(finished - exit code 0) ['/usr/bin/zsh', '-c', 'cd ''/home/ndtho8205/Desktop/kotlin-maven-example'' && mvn dependency:build-classpath']

<<<OUTPUT STARTS>>>
[INFO] Scanning for projects...
[INFO] 
[INFO] ---------< org.jetbrains.kotlin.examples:dagger-maven-example >---------
[INFO] Building dagger-maven-example 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:build-classpath (default-cli) @ dagger-maven-example ---
[INFO] Dependencies classpath:
/home/ndtho8205/.m2/repository/com/google/dagger/dagger/2.9/dagger-2.9.jar:/home/ndtho8205/.m2/repository/javax/inject/javax.inject/1/javax.inject-1.jar:/home/ndtho8205/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.3.72/kotlin-stdlib-1.3.72.jar:/home/ndtho8205/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.72/kotlin-stdlib-common-1.3.72.jar:/home/ndtho8205/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/home/ndtho8205/.m2/repository/junit/junit/4.12/junit-4.12.jar:/home/ndtho8205/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.655 s
[INFO] Finished at: 2020-04-19T16:00:55+09:00
[INFO] ------------------------------------------------------------------------
<<<OUTPUT ENDS>>>

(executable check - failure) ktlint
(executable check - failure) kotlin-language-server
(finished - exit code 1) ['/usr/bin/zsh', '-c', 'kotlinc  -cp ''/home/ndtho8205/.m2/repository/com/google/dagger/dagger/2.9/dagger-2.9.jar:/home/ndtho8205/.m2/repository/javax/inject/javax.inject/1/javax.inject-1.jar:/home/ndtho8205/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.3.72/kotlin-stdlib-1.3.72.jar:/home/ndtho8205/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.72/kotlin-stdlib-common-1.3.72.jar:/home/ndtho8205/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/home/ndtho8205/.m2/repository/junit/junit/4.12/junit-4.12.jar:/home/ndtho8205/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar''  /home/ndtho8205/Desktop/kotlin-maven-example/src/main/kotlin/ ''/home/ndtho8205/Desktop/kotlin-maven-example/src/main/kotlin/CoffeeApp.kt''']

<<<OUTPUT STARTS>>>
src/main/kotlin/CoffeeApp.kt:15:22: error: unresolved reference: DaggerCoffeeApp_Coffee
        val coffee = DaggerCoffeeApp_Coffee.builder().build()
                     ^
src/main/kotlin/CoffeeApp.kt:16:9: error: unresolved reference: offee
        offee.maker().brew()
        ^
<<<OUTPUT ENDS>>>

Thanks, was able to verify the PR works as expected.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

glepnir picture glepnir  路  3Comments

trevordmiller picture trevordmiller  路  3Comments

amerov picture amerov  路  4Comments

ilyakopy picture ilyakopy  路  4Comments

garand picture garand  路  4Comments