Merge pull request #2087 from m-pilia/ada

Add GCC linter for Ada
This commit is contained in:
w0rp 2018-11-19 19:36:32 +00:00 committed by GitHub
commit 4b4b09593b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 163 additions and 0 deletions

View File

@ -97,6 +97,7 @@ formatting.
| Language | Tools | | Language | Tools |
| -------- | ----- | | -------- | ----- |
| Ada | [gcc](https://gcc.gnu.org) |
| ASM | [gcc](https://gcc.gnu.org) | | ASM | [gcc](https://gcc.gnu.org) |
| Ansible | [ansible-lint](https://github.com/willthames/ansible-lint) | | Ansible | [ansible-lint](https://github.com/willthames/ansible-lint) |
| API Blueprint | [drafter](https://github.com/apiaryio/drafter) | | API Blueprint | [drafter](https://github.com/apiaryio/drafter) |

54
ale_linters/ada/gcc.vim Normal file
View File

@ -0,0 +1,54 @@
" Author: Martino Pilia <martino.pilia@gmail.com>
" Description: Lint Ada files with GCC
call ale#Set('ada_gcc_executable', 'gcc')
" -gnatwa: activate most optional warnings
" -gnatq: try semantic analysis even if syntax errors have been found
call ale#Set('ada_gcc_options', '-gnatwa -gnatq')
function! ale_linters#ada#gcc#GetCommand(buffer) abort
" Build a suitable output file name. The output file is specified because
" the .ali file may be created even if no code generation is attempted.
" The output file name must match the source file name (except for the
" extension), so here we cannot use the null file as output.
let l:tmp_dir = fnamemodify(ale#engine#CreateDirectory(a:buffer), ':p')
let l:out_file = l:tmp_dir . fnamemodify(bufname(a:buffer), ':t:r') . '.o'
" -gnatc: Check syntax and semantics only (no code generation attempted)
return '%e -x ada -c -gnatc'
\ . ' -o ' . ale#Escape(l:out_file)
\ . ' -I ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
\ . ale#Pad(ale#Var(a:buffer, 'ada_gcc_options'))
\ . ' %t'
endfunction
" For the message format please refer to:
" https://gcc.gnu.org/onlinedocs/gnat_ugn/Output-and-Error-Message-Control.html
" https://gcc.gnu.org/onlinedocs/gnat_ugn/Warning-Message-Control.html
function! ale_linters#ada#gcc#Handle(buffer, lines) abort
" Error format: <filename>:<lnum>:<col>: <text>
" Warning format: <filename>:<lnum>:<col>: warning: <text>
let l:re = '\v(.+):([0-9]+):([0-9]+):\s+(warning:)?\s*(.+)\s*'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:re)
call add(l:output, {
\ 'bufnr': a:buffer,
\ 'lnum': str2nr(l:match[2]),
\ 'col': str2nr(l:match[3]),
\ 'type': l:match[4] is# 'warning:' ? 'W' : 'E',
\ 'text': l:match[5],
\})
endfor
return l:output
endfunction
call ale#linter#Define('ada', {
\ 'name': 'gcc',
\ 'output_stream': 'stderr',
\ 'executable_callback': ale#VarFunc('ada_gcc_executable'),
\ 'command_callback': 'ale_linters#ada#gcc#GetCommand',
\ 'callback': 'ale_linters#ada#gcc#Handle',
\})

25
doc/ale-ada.txt Normal file
View File

@ -0,0 +1,25 @@
===============================================================================
ALE Ada Integration *ale-ada-options*
===============================================================================
gcc *ale-ada-gcc*
g:ale_ada_gcc_executable *g:ale_ada_gcc_executable*
*b:ale_ada_gcc_executable*
Type: |String|
Default: `'gcc'`
This variable can be changed to use a different executable for gcc.
g:ale_ada_gcc_options *g:ale_ada_gcc_options*
*b:ale_ada_gcc_options*
Type: |String|
Default: `'-gnatwa -gnatq'`
This variable can be set to pass additional options to gcc.
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@ -21,6 +21,8 @@ CONTENTS *ale-contents*
6.1 Highlights........................|ale-highlights| 6.1 Highlights........................|ale-highlights|
6.2 Options for write-good Linter.....|ale-write-good-options| 6.2 Options for write-good Linter.....|ale-write-good-options|
7. Integration Documentation............|ale-integrations| 7. Integration Documentation............|ale-integrations|
ada...................................|ale-ada-options|
gcc.................................|ale-ada-gcc|
ansible...............................|ale-ansible-options| ansible...............................|ale-ansible-options|
ansible-lint........................|ale-ansible-ansible-lint| ansible-lint........................|ale-ansible-ansible-lint|
asciidoc..............................|ale-asciidoc-options| asciidoc..............................|ale-asciidoc-options|
@ -392,6 +394,7 @@ Notes:
`^` No linters for text or Vim help filetypes are enabled by default. `^` No linters for text or Vim help filetypes are enabled by default.
`!!` These linters check only files on disk. See |ale-lint-file-linters| `!!` These linters check only files on disk. See |ale-lint-file-linters|
* Ada: `gcc`
* ASM: `gcc` * ASM: `gcc`
* Ansible: `ansible-lint` * Ansible: `ansible-lint`
* API Blueprint: `drafter` * API Blueprint: `drafter`

View File

@ -0,0 +1,44 @@
Before:
call ale#assert#SetUpLinterTest('ada', 'gcc')
call ale#test#SetFilename('dummy.adb')
function! GetOutputDir(command) abort
let l:split_command = split(a:command)
let l:index = index(l:split_command, '-o')
return l:split_command[l:index + 1]
endfunction
let b:out_file = GetOutputDir(ale_linters#ada#gcc#GetCommand(bufnr('')))
After:
delfunction GetOutputDir
unlet! b:out_file
call ale#assert#TearDownLinterTest()
Execute(The executable should be configurable):
AssertLinter 'gcc',
\ ale#Escape('gcc') . ' -x ada -c -gnatc'
\ . ' -o ' . b:out_file
\ . ' -I ' . ale#Escape(getcwd())
\ . ' -gnatwa -gnatq %t'
let b:ale_ada_gcc_executable = 'foo'
AssertLinter 'foo',
\ ale#Escape('foo') . ' -x ada -c -gnatc'
\ . ' -o ' . b:out_file
\ . ' -I ' . ale#Escape(getcwd())
\ . ' -gnatwa -gnatq %t'
Execute(The options should be configurable):
let g:ale_ada_gcc_options = '--foo --bar'
AssertLinter 'gcc',
\ ale#Escape('gcc') . ' -x ada -c -gnatc'
\ . ' -o ' . b:out_file
\ . ' -I ' . ale#Escape(getcwd())
\ . ' --foo --bar %t'

View File

@ -0,0 +1,36 @@
Before:
runtime ale_linters/ada/gcc.vim
After:
call ale#linter#Reset()
Execute(The gcc handler for Ada should parse input correctly):
AssertEqual
\ [
\ {
\ 'bufnr': 0,
\ 'lnum': 8,
\ 'col': 5,
\ 'type': 'W',
\ 'text': 'variable "X" is assigned but never read',
\ },
\ {
\ 'bufnr': 0,
\ 'lnum': 6,
\ 'col': 22,
\ 'type': 'E',
\ 'text': 'type definition expected',
\ },
\ {
\ 'bufnr': 0,
\ 'lnum': 8,
\ 'col': 9,
\ 'type': 'E',
\ 'text': 'aspect specifications not allowed here',
\ },
\ ],
\ ale_linters#ada#gcc#Handle(0, [
\ 'foobar.adb:8:05: warning: variable "X" is assigned but never read',
\ 'foobar.ads:6:22: type definition expected',
\ 'foobar.ads:8:09: aspect specifications not allowed here',
\ ])