summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorw0rp <devw0rp@gmail.com>2017-07-27 13:24:28 +0100
committerw0rp <devw0rp@gmail.com>2017-07-27 13:24:32 +0100
commit63b9d9e9df9811eec3470e38b234cd2d959169eb (patch)
treeb267b7c73039342e33eb036893c2076b5fa5bc5d
parentfa33faad9ed6da220394bd2abec2e1bdcd19edba (diff)
downloadale-63b9d9e9df9811eec3470e38b234cd2d959169eb.zip
Fix #798 - Handle syntax errors for tsserver
-rw-r--r--autoload/ale/engine.vim31
-rw-r--r--test/test_engine_lsp_response_handling.vader155
2 files changed, 181 insertions, 5 deletions
diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim
index 8bef01d7..d66126ab 100644
--- a/autoload/ale/engine.vim
+++ b/autoload/ale/engine.vim
@@ -200,21 +200,42 @@ function! s:HandleLSPDiagnostics(response) abort
call s:HandleLoclist('langserver', l:buffer, l:loclist)
endfunction
-function! s:HandleTSServerDiagnostics(response) abort
+function! s:HandleTSServerDiagnostics(response, error_type) abort
let l:buffer = bufnr(a:response.body.file)
- let l:loclist = ale#lsp#response#ReadTSServerDiagnostics(a:response)
+ let l:info = get(g:ale_buffer_info, l:buffer, {})
+
+ if empty(l:info)
+ return
+ endif
+
+ let l:thislist = ale#lsp#response#ReadTSServerDiagnostics(a:response)
+
+ " tsserver sends syntax and semantic errors in separate messages, so we
+ " have to collect the messages separately for each buffer and join them
+ " back together again.
+ if a:error_type ==# 'syntax'
+ let l:info.syntax_loclist = l:thislist
+ else
+ let l:info.semantic_loclist = l:thislist
+ endif
+
+ let l:loclist = get(l:info, 'semantic_loclist', [])
+ \ + get(l:info, 'syntax_loclist', [])
call s:HandleLoclist('tsserver', l:buffer, l:loclist)
endfunction
-function! s:HandleLSPResponse(response) abort
+function! ale#engine#HandleLSPResponse(response) abort
let l:method = get(a:response, 'method', '')
if l:method ==# 'textDocument/publishDiagnostics'
call s:HandleLSPDiagnostics(a:response)
elseif get(a:response, 'type', '') ==# 'event'
\&& get(a:response, 'event', '') ==# 'semanticDiag'
- call s:HandleTSServerDiagnostics(a:response)
+ call s:HandleTSServerDiagnostics(a:response, 'semantic')
+ elseif get(a:response, 'type', '') ==# 'event'
+ \&& get(a:response, 'event', '') ==# 'syntaxDiag'
+ call s:HandleTSServerDiagnostics(a:response, 'syntax')
endif
endfunction
@@ -575,7 +596,7 @@ function! s:CheckWithLSP(buffer, linter) abort
let l:lsp_details = ale#linter#StartLSP(
\ a:buffer,
\ a:linter,
- \ function('s:HandleLSPResponse'),
+ \ function('ale#engine#HandleLSPResponse'),
\)
if empty(l:lsp_details)
diff --git a/test/test_engine_lsp_response_handling.vader b/test/test_engine_lsp_response_handling.vader
new file mode 100644
index 00000000..1f766baf
--- /dev/null
+++ b/test/test_engine_lsp_response_handling.vader
@@ -0,0 +1,155 @@
+Before:
+ Save g:ale_buffer_info
+ call ale#test#SetDirectory('/testplugin/test')
+
+After:
+ Restore
+
+ call ale#test#RestoreDirectory()
+ call ale#linter#Reset()
+
+Execute(tsserver syntax error responses should be handled correctly):
+ runtime ale_linters/typescript/tsserver.vim
+ call ale#test#SetFilename('filename.ts')
+ call ale#engine#InitBufferInfo(bufnr(''))
+
+ " When we get syntax errors and no semantic errors, we should keep the
+ " syntax errors.
+ call ale#engine#HandleLSPResponse({
+ \ 'seq': 0,
+ \ 'type': 'event',
+ \ 'event': 'syntaxDiag',
+ \ 'body': {
+ \ 'file': g:dir . '/filename.ts',
+ \ 'diagnostics':[
+ \ {
+ \ 'start': {
+ \ 'line':2,
+ \ 'offset':14,
+ \ },
+ \ 'end': {
+ \ 'line':2,
+ \ 'offset':15,
+ \ },
+ \ 'text': ''','' expected.',
+ \ "code":1005
+ \ },
+ \ ],
+ \ },
+ \})
+ call ale#engine#HandleLSPResponse({
+ \ 'seq': 0,
+ \ 'type': 'event',
+ \ 'event': 'semanticDiag',
+ \ 'body': {
+ \ 'file': g:dir . '/filename.ts',
+ \ 'diagnostics':[
+ \ ],
+ \ },
+ \})
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 1,
+ \ 'bufnr': bufnr(''),
+ \ 'col': 14,
+ \ 'vcol': 0,
+ \ 'nr': 1005,
+ \ 'type': 'E',
+ \ 'text': ''','' expected.',
+ \ 'valid': 1,
+ \ 'pattern': '',
+ \ },
+ \ ],
+ \ getloclist(0)
+
+ " After we get empty syntax errors, we should clear them.
+ call ale#engine#HandleLSPResponse({
+ \ 'seq': 0,
+ \ 'type': 'event',
+ \ 'event': 'syntaxDiag',
+ \ 'body': {
+ \ 'file': g:dir . '/filename.ts',
+ \ 'diagnostics':[
+ \ ],
+ \ },
+ \})
+
+ AssertEqual
+ \ [
+ \ ],
+ \ getloclist(0)
+
+Execute(tsserver semantic error responses should be handled correctly):
+ runtime ale_linters/typescript/tsserver.vim
+ call ale#test#SetFilename('filename.ts')
+ call ale#engine#InitBufferInfo(bufnr(''))
+
+ " When we get syntax errors and no semantic errors, we should keep the
+ " syntax errors.
+ call ale#engine#HandleLSPResponse({
+ \ 'seq': 0,
+ \ 'type': 'event',
+ \ 'event': 'syntaxDiag',
+ \ 'body': {
+ \ 'file': g:dir . '/filename.ts',
+ \ 'diagnostics':[
+ \ ],
+ \ },
+ \})
+ call ale#engine#HandleLSPResponse({
+ \ 'seq': 0,
+ \ 'type': 'event',
+ \ 'event': 'semanticDiag',
+ \ 'body': {
+ \ 'file': g:dir . '/filename.ts',
+ \ 'diagnostics':[
+ \ {
+ \ 'start': {
+ \ 'line':2,
+ \ 'offset':14,
+ \ },
+ \ 'end': {
+ \ 'line':2,
+ \ 'offset':15,
+ \ },
+ \ 'text': 'Some semantic error',
+ \ "code":1005
+ \ },
+ \ ],
+ \ },
+ \})
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 1,
+ \ 'bufnr': bufnr(''),
+ \ 'col': 14,
+ \ 'vcol': 0,
+ \ 'nr': 1005,
+ \ 'type': 'E',
+ \ 'text': 'Some semantic error',
+ \ 'valid': 1,
+ \ 'pattern': '',
+ \ },
+ \ ],
+ \ getloclist(0)
+
+ " After we get empty syntax errors, we should clear them.
+ call ale#engine#HandleLSPResponse({
+ \ 'seq': 0,
+ \ 'type': 'event',
+ \ 'event': 'semanticDiag',
+ \ 'body': {
+ \ 'file': g:dir . '/filename.ts',
+ \ 'diagnostics':[
+ \ ],
+ \ },
+ \})
+
+ AssertEqual
+ \ [
+ \ ],
+ \ getloclist(0)