vim-syntastic / syntastic

Syntax checking hacks for vim
Do What The F*ck You Want To Public License
11.3k stars 1.14k forks source link

Issues with scalac #1996

Closed ghost closed 7 years ago

ghost commented 7 years ago

When using Vim + Syntastic for Scala development, the scalac compiler does not seem to work properly: some errors and warnings aren't reported, even when actually present. However, some are: mainly, anything written OUTSIDE class/object definitions (which, given the nature of the language, isn't really that useful).

When running :SyntasticInfo I can see that scalac is enabled and active, so I can't seem to be able to explain this strange behavior. My Vim version is 7.4.1689 on Linux Mint 18.1, and scalac version is 2.12.1 (latest version at the time of writing, downloaded directly from the official website and not from Mint's repos). No issues so far with other compilers and checkers for other languages, including, but not limited to: gcc, g++, javac, pylint, sbcl, ghc, ocaml.

lcd047 commented 7 years ago

Syntastic works by parsing the output of linters. Now, some linters makes this easy, by sending all their messages through a centralized logging functions, or by using a structured output format such as JSON. Syntastic generally works fine with these linters.

Other linters however have 533 ad-hoc functions for logging 533 messages, each in a slightly different format. Elixir is an example of such linter. Syntastic will never work correctly with these linters. Syntastic checkers should never have been written for these linters, yet some people still find them useful. I don't remember if this is the case for Scala.

Finally, there is a third possibility: the output format of a linter has changed since a Syntastic checker was written for it. In this case the checker can usually be updated.

Now, if you want a more specific answer you'll need to provide logs: open your test file, set g:syntastic_debug to 3, run the checker, run :mes, and post the output. Also post the output of the equivalent run in a terminal.

ghost commented 7 years ago

Sorry for the late reply, here are some logs. The sample file I used is:

import akka.actor.Actor
import akka.actor.ActorSystem
import akka.actor.Props

class HelloActor extends Actor {
  def receive = {
    case "hello" => println("hello back at you")
    case _       => println("huh?")
  }
  obvious_error
}

ext_error

object Main extends App {
  val system = ActorSystem("HelloSystem")
  // default Actor constructor
  val helloActor = system.actorOf(Props[HelloActor], name = "helloactor")
  println("Before sending...")
  helloActor ! "hello"
  println("After hello")
  helloActor ! "buenos dias"
  println("After buenos dias")
}

Which clearly contains two errors, in lines 10 and 13 respectively, yet only latter is correctly detected by Syntastic. The log is

Messages maintainer: Bram Moolenaar <Bram@vim.org>
"example.scala" 24L, 563C
syntastic: 18.168902: &shell = '/bin/bash', &shellcmdflag = '-c', &shellpipe = '2>&1| tee', &shellquote = '', &shellredir = '>%s 2>&1', &shellslash = 0, &shelltemp = 1, &shellxquote = '', &shellxescape = ''
syntastic: 18.169922: UpdateErrors: default checkers
syntastic: 18.171241: CacheErrors: default checkers
syntastic: 18.172433: g:syntastic_aggregate_errors = 1
syntastic: 18.172556: getcwd() = /home/cosimone/example
syntastic: 18.173798: CacheErrors: Invoking checker: scala/fsc
syntastic: 18.174476: SyntasticMake: called with options: {'errorformat': '%E%f:%l: %trror: %m,%Z%p^,%-G%.%#', 'makeprg': 'fsc -Ystop-after:parser /home/cosimone/example/example.scala'}
syntastic: 19.147996: checker output: ['cat: /release: No such file or directory', '/home/cosimone/example/example.scala:13: error: expected class or object definition', 'ext_error', '^', 'one error found', '']
syntastic: 19.148478: raw loclist: [{'lnum': 13, 'bufnr': 1, 'col': 1, 'valid': 1, 'vcol': 1, 'nr': -1, 'type': 'e', 'pattern': '', 'text': 'expected class or object definition'}]
syntastic: 19.148743: getLocList: checker scala/fsc returned 1
syntastic: 19.148900: scala/fsc raw: [{'lnum': 13, 'bufnr': 1, 'col': 1, 'valid': 1, 'vcol': 1, 'nr': -1, 'type': 'e', 'pattern': '', 'text': 'expected class or object definition'}]
syntastic: 19.149056: quiet_messages filter: {}
syntastic: 19.149705: CacheErrors: Invoking checker: scala/scalac

It does seem that some error detection is clearly happening behind the curtain, but only for the error that is correctly being detected, and not for the other one.

lcd047 commented 7 years ago

Well, this is very different from what you seem to believe. Here you see fsc being run:

syntastic: 18.174476: SyntasticMake: called with options: {'errorformat': '%E%f:%l: %trror: %m,%Z%p^,%-G%.%#', 'makeprg': 'fsc -Ystop-after:parser /home/cosimone/example/example.scala'}

It finds a single error:

syntastic: 19.147996: checker output: ['cat: /release: No such file or directory', '/home/cosimone/example/example.scala:13: error: expected class or object definition', 'ext_error', '^', 'one error found', '']

(The message cat: /release: No such file or directory seems suspicious too, but that has nothing to do with syntastic.) Then you see syntastic correctly parsing the one error, and converting it to a loclist:

syntastic: 19.148478: raw loclist: [{'lnum': 13, 'bufnr': 1, 'col': 1, 'valid': 1, 'vcol': 1, 'nr': -1, 'type': 'e', 'pattern': '', 'text': 'expected class or object definition'}]

Syntastic doesn't know, nor cares, about the contents of your files. What syntastic does is run third-party linters, parse their output, and show you the results in a window. This is working fine above. Why you get a single error instead of two above is a question for the fsc maintainers. Feel free to report problems here if you can point to a case where fsc finds a number of errors when you run it from a terminal and syntastic doesn't show all of them in a window. The other way around, fsc not finding all errors you expect, has nothing to do with syntastic. shrug