From 7112776d1b04d2cb01a1b01c0edfa5b86ed88e99 Mon Sep 17 00:00:00 2001 From: w0rp Date: Sun, 20 Aug 2017 00:05:15 +0100 Subject: [PATCH] #653 Update tslint to set the filename key for problems in other files --- ale_linters/typescript/tslint.vim | 31 +++++++++-------- autoload/ale/engine.vim | 11 +++--- autoload/ale/path.vim | 13 +++++++ .../test_tslint_command_callback.vader | 24 +++++++++++++ test/handler/test_tslint_handler.vader | 34 +++++++++++++------ test/test_get_abspath.vader | 15 ++++++++ test/test_loclist_corrections.vader | 2 -- 7 files changed, 96 insertions(+), 34 deletions(-) create mode 100644 test/command_callback/test_tslint_command_callback.vader create mode 100644 test/test_get_abspath.vader diff --git a/ale_linters/typescript/tslint.vim b/ale_linters/typescript/tslint.vim index 4db5094..26d26c8 100644 --- a/ale_linters/typescript/tslint.vim +++ b/ale_linters/typescript/tslint.vim @@ -12,27 +12,27 @@ function! ale_linters#typescript#tslint#GetExecutable(buffer) abort endfunction function! ale_linters#typescript#tslint#Handle(buffer, lines) abort + let l:dir = expand('#' . a:buffer . ':p:h') let l:output = [] for l:error in ale#util#FuzzyJSONDecode(a:lines, []) - if ale#path#IsBufferPath(a:buffer, l:error.name) - call add(l:output, { - \ 'type': (get(l:error, 'ruleSeverity', '') is# 'WARNING' ? 'W' : 'E'), - \ 'text': has_key(l:error, 'ruleName') - \ ? l:error.ruleName . ': ' . l:error.failure - \ : l:error.failure, - \ 'lnum': l:error.startPosition.line + 1, - \ 'col': l:error.startPosition.character + 1, - \ 'end_lnum': l:error.endPosition.line + 1, - \ 'end_col': l:error.endPosition.character + 1, - \}) - endif + call add(l:output, { + \ 'filename': ale#path#GetAbsPath(l:dir, l:error.name), + \ 'type': (get(l:error, 'ruleSeverity', '') is# 'WARNING' ? 'W' : 'E'), + \ 'text': has_key(l:error, 'ruleName') + \ ? l:error.ruleName . ': ' . l:error.failure + \ : l:error.failure, + \ 'lnum': l:error.startPosition.line + 1, + \ 'col': l:error.startPosition.character + 1, + \ 'end_lnum': l:error.endPosition.line + 1, + \ 'end_col': l:error.endPosition.character + 1, + \}) endfor return l:output endfunction -function! ale_linters#typescript#tslint#BuildLintCommand(buffer) abort +function! ale_linters#typescript#tslint#GetCommand(buffer) abort let l:tslint_config_path = ale#path#ResolveLocalPath( \ a:buffer, \ 'tslint.json', @@ -43,7 +43,8 @@ function! ale_linters#typescript#tslint#BuildLintCommand(buffer) abort \ ? ' -c ' . ale#Escape(l:tslint_config_path) \ : '' - return ale_linters#typescript#tslint#GetExecutable(a:buffer) + return ale#path#BufferCdString(a:buffer) + \ . ale_linters#typescript#tslint#GetExecutable(a:buffer) \ . ' --format json' \ . l:tslint_config_option \ . ' %t' @@ -52,6 +53,6 @@ endfunction call ale#linter#Define('typescript', { \ 'name': 'tslint', \ 'executable_callback': 'ale_linters#typescript#tslint#GetExecutable', -\ 'command_callback': 'ale_linters#typescript#tslint#BuildLintCommand', +\ 'command_callback': 'ale_linters#typescript#tslint#GetCommand', \ 'callback': 'ale_linters#typescript#tslint#Handle', \}) diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim index 6a16895..4093003 100644 --- a/autoload/ale/engine.vim +++ b/autoload/ale/engine.vim @@ -362,6 +362,7 @@ function! ale#engine#FixLocList(buffer, linter_name, loclist) abort " The linter_name will be set on the errors so it can be used in " output, filtering, etc.. let l:item = { + \ 'bufnr': a:buffer, \ 'text': l:old_item.text, \ 'lnum': str2nr(l:old_item.lnum), \ 'col': str2nr(get(l:old_item, 'col', 0)), @@ -372,7 +373,11 @@ function! ale#engine#FixLocList(buffer, linter_name, loclist) abort \} if has_key(l:old_item, 'filename') + \&& l:old_item.filename[:len(s:temp_dir) - 1] isnot# s:temp_dir " Use the filename given. + " Temporary files are assumed to be for this buffer, + " and the filename is not included then, because it looks bad + " in the loclist window. let l:filename = l:old_item.filename let l:item.filename = l:filename @@ -384,10 +389,6 @@ function! ale#engine#FixLocList(buffer, linter_name, loclist) abort elseif has_key(l:bufnr_map, l:filename) " Get the buffer number from the map, which can be faster. let l:item.bufnr = l:bufnr_map[l:filename] - elseif l:filename[:len(s:temp_dir) - 1] is# s:temp_dir - " Assume that any temporary files are for this buffer. - let l:item.bufnr = a:buffer - let l:bufnr_map[l:filename] = a:buffer else " Look up the buffer number. let l:item.bufnr = bufnr(l:filename) @@ -395,8 +396,6 @@ function! ale#engine#FixLocList(buffer, linter_name, loclist) abort endif elseif has_key(l:old_item, 'bufnr') let l:item.bufnr = l:old_item.bufnr - else - let l:item.bufnr = a:buffer endif if has_key(l:old_item, 'detail') diff --git a/autoload/ale/path.vim b/autoload/ale/path.vim index 4906947..bc026cc 100644 --- a/autoload/ale/path.vim +++ b/autoload/ale/path.vim @@ -86,6 +86,19 @@ function! ale#path#IsTempName(filename) abort return 0 endfunction +" Given a base directory, which must not have a trailing slash, and a +" filename, which may have an absolute path a path relative to the base +" directory, return the absolute path to the file. +function! ale#path#GetAbsPath(base_directory, filename) abort + if ale#path#IsAbsolute(a:filename) + return a:filename + endif + + let l:sep = has('win32') ? '\' : '/' + + return ale#path#Simplify(a:base_directory . l:sep . a:filename) +endfunction + " Given a buffer number and a relative or absolute path, return 1 if the " two paths represent the same file on disk. function! ale#path#IsBufferPath(buffer, complex_filename) abort diff --git a/test/command_callback/test_tslint_command_callback.vader b/test/command_callback/test_tslint_command_callback.vader new file mode 100644 index 0000000..694d36d --- /dev/null +++ b/test/command_callback/test_tslint_command_callback.vader @@ -0,0 +1,24 @@ +Before: + Save g:typescript_tslint_executable + Save g:typescript_tslint_config_path + Save g:typescript_tslint_use_global + + unlet! g:typescript_tslint_executable + unlet! g:typescript_tslint_config_path + unlet! g:typescript_tslint_use_global + + runtime ale_linters/typescript/tslint.vim + + call ale#test#SetDirectory('/testplugin/test/command_callback') + +After: + Restore + + call ale#test#RestoreDirectory() + call ale#linter#Reset() + +Execute(The default tslint command should be correct): + AssertEqual + \ 'cd ''' . expand('%:p:h') . ''' && ' + \ . 'tslint --format json %t', + \ ale_linters#typescript#tslint#GetCommand(bufnr('')) diff --git a/test/handler/test_tslint_handler.vader b/test/handler/test_tslint_handler.vader index a27657e..5c8679a 100644 --- a/test/handler/test_tslint_handler.vader +++ b/test/handler/test_tslint_handler.vader @@ -15,28 +15,40 @@ Execute(The tslint handler should parse lines correctly): \ { \ 'lnum': 1, \ 'col': 15, + \ 'filename': expand('%:p:h') . '/test.ts', \ 'end_lnum': 1, - \ 'end_col': 15, - \ 'text': 'semicolon: Missing semicolon', \ 'type': 'E', + \ 'end_col': 15, + \ 'text': 'semicolon: Missing semicolon' \ }, \ { \ 'lnum': 2, \ 'col': 8, + \ 'filename': expand('%:p:h') . '/test.ts', \ 'end_lnum': 3, - \ 'end_col': 12, - \ 'text': 'Something else', \ 'type': 'W', + \ 'end_col': 12, + \ 'text': 'Something else' + \ }, + \ { + \ 'lnum': 2, + \ 'col': 8, + \ 'filename': expand('%:p:h') . '/something-else.ts', + \ 'end_lnum': 3, + \ 'type': 'W', + \ 'end_col': 12, + \ 'text': 'something: Something else' \ }, \ { \ 'lnum': 31, \ 'col': 9, + \ 'filename': expand('%:p:h') . '/test.ts', \ 'end_lnum': 31, - \ 'end_col': 20, - \ 'text': 'no-console: Calls to console.log are not allowed.', \ 'type': 'E', + \ 'end_col': 20, + \ 'text': 'no-console: Calls to console.log are not allowed.' \ }, - \ ], + \ ] , \ ale_linters#typescript#tslint#Handle(bufnr(''), [json_encode([ \ { \ 'endPosition': { @@ -50,7 +62,7 @@ Execute(The tslint handler should parse lines correctly): \ 'innerStart': 14, \ 'innerText': ';' \ }, - \ 'name': 'app/test.ts', + \ 'name': 'test.ts', \ 'ruleName': 'semicolon', \ 'ruleSeverity': 'ERROR', \ 'startPosition': { @@ -71,7 +83,7 @@ Execute(The tslint handler should parse lines correctly): \ 'innerStart': 14, \ 'innerText': ';' \ }, - \ 'name': 'app/test.ts', + \ 'name': 'test.ts', \ 'ruleSeverity': 'WARNING', \ 'startPosition': { \ 'character': 7, @@ -91,7 +103,7 @@ Execute(The tslint handler should parse lines correctly): \ 'innerStart': 14, \ 'innerText': ';' \ }, - \ 'name': 'app/something-else.ts', + \ 'name': 'something-else.ts', \ 'ruleName': 'something', \ 'ruleSeverity': 'WARNING', \ 'startPosition': { @@ -107,7 +119,7 @@ Execute(The tslint handler should parse lines correctly): \ "position": 14590 \ }, \ "failure": "Calls to console.log are not allowed.", - \ 'name': 'app/test.ts', + \ 'name': 'test.ts', \ "ruleName": "no-console", \ "startPosition": { \ "character": 8, diff --git a/test/test_get_abspath.vader b/test/test_get_abspath.vader new file mode 100644 index 0000000..2def377 --- /dev/null +++ b/test/test_get_abspath.vader @@ -0,0 +1,15 @@ +Execute(Relative paths should be resolved correctly): + AssertEqual + \ '/foo/bar/baz/whatever.txt', + \ ale#path#GetAbsPath('/foo/bar/xyz', '../baz/whatever.txt') + AssertEqual + \ '/foo/bar/xyz/whatever.txt', + \ ale#path#GetAbsPath('/foo/bar/xyz', './whatever.txt') + AssertEqual + \ '/foo/bar/xyz/whatever.txt', + \ ale#path#GetAbsPath('/foo/bar/xyz', 'whatever.txt') + +Execute(Absolute paths should be resolved correctly): + AssertEqual + \ '/ding/dong', + \ ale#path#GetAbsPath('/foo/bar/xyz', '/ding/dong') diff --git a/test/test_loclist_corrections.vader b/test/test_loclist_corrections.vader index e0a21da..e6844d8 100644 --- a/test/test_loclist_corrections.vader +++ b/test/test_loclist_corrections.vader @@ -303,7 +303,6 @@ Execute(FixLocList should interpret temporary filenames as being the current buf \ 'lnum': 2, \ 'col': 0, \ 'bufnr': bufnr(''), - \ 'filename': b:temp_name, \ 'vcol': 0, \ 'type': 'E', \ 'nr': -1, @@ -314,7 +313,6 @@ Execute(FixLocList should interpret temporary filenames as being the current buf \ 'lnum': 3, \ 'col': 0, \ 'bufnr': bufnr(''), - \ 'filename': b:temp_name, \ 'vcol': 0, \ 'type': 'E', \ 'nr': -1,