Added advanced c-sharp linter

The existing c-charp linter used the --syntax check mode of the mono mcs
compiler only. The new mcsc linter tries to compile the files located in
a directory tree located bejond the specified source directory or the
current one if no source is explicitly specified. The resulting module
target is placed in a temporary file managed by ale.
This commit is contained in:
Xristoph Hintermüller 2017-09-25 12:54:50 +02:00
parent 2bd352370f
commit cde50f1091
2 changed files with 161 additions and 0 deletions

86
ale_linters/cs/mcsc.vim Normal file
View file

@ -0,0 +1,86 @@
let g:ale_cs_mcsc_options = get(g:, 'ale_cs_mcsc_options', '')
let g:ale_cs_mcsc_source = get(g:,'ale_cs_mcsc_source','')
let g:ale_cs_mcsc_assembly_path = get(g:,'ale_cs_mcsc_assembly_path',[])
let g:ale_cs_mcsc_assemblies = get(g:,'ale_cs_mcsc_assemblies',[])
function! ale_linters#cs#mcsc#GetCommand(buffer) abort
let l:path = ale#Var(a:buffer,'cs_mcsc_assembly_path')
if !empty(l:path)
if type(l:path) == type('')
let l:path = '-lib:' . l:path
elseif type(l:path) == type([])
let l:path = '-lib:' . join(l:path,',')
else
throw 'assembly path list must be string or list of path strings'
endif
elseif type(l:path) != type('')
if type(l:path) != type([])
throw 'assembly path list must be string or list of path strings'
endif
let l:path =''
endif
let l:assemblies = ale#Var(a:buffer,'cs_mcsc_assemblies')
if !empty(l:assemblies)
if type(l:assemblies) == type('')
let l:assemblies = '-r' . l:assemblies
elseif type(l:assemblies) == type([])
let l:assemblies = '-r:' . join(l:assemblies,',')
else
throw 'assembly list must be string or list of strings'
endif
elseif type(l:assemblies) != type('')
if type(l:assemblies) != type([])
throw 'assembly list must be string or list of string'
endif
let l:assemblies =''
endif
let l:base = ale#Var(a:buffer,'cs_mcsc_source')
let l:cwd = getcwd()
if isdirectory(l:base)
exe 'cd ' . l:base
elseif empty(l:base) && ( type(l:base) == type('') )
let l:base = '.'
else
throw 'ale_cs_mcs_source must point to an existing directory or empty string for current'
endif
let l:out = tempname()
call ale#engine#ManageFile(a:buffer,l:out)
let l:cmd = 'cd ' . l:base . ';'
\ . 'mcs -unsafe'
\ . ' ' . ale#Var(a:buffer, 'cs_mcsc_options')
\ . ' ' . l:path
\ . ' ' . l:assemblies
\ . ' -out:' . l:out
\ . ' -t:module'
\ . ' "' . join(glob('**/*.cs',v:false,v:true),'" "') . '"'
exe 'cd ' . l:cwd
return l:cmd
endfunction
function! ale_linters#cs#mcsc#Handle(buffer, lines) abort
" Look for lines like the following.
"
" Tests.cs(12,29): error CSXXXX: ; expected
let l:pattern = '^\(.\+\.cs\)(\(\d\+\),\(\d\+\)): \(.\+\): \(.\+\)'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'filename': l:match[1],
\ 'lnum': l:match[2] + 0,
\ 'col': l:match[3] + 0,
\ 'text': l:match[4] . ': ' . l:match[5],
\ 'type': l:match[4] =~# '^error' ? 'E' : 'W',
\})
endfor
return l:output
endfunction
call ale#linter#Define('cs',{
\ 'name': 'mcsc',
\ 'output_stream': 'stderr',
\ 'executable': 'mcs',
\ 'command_callback': 'ale_linters#cs#mcsc#GetCommand',
\ 'callback': 'ale_linters#cs#mcsc#Handle',
\ 'lint_file': 1
\})

75
doc/ale-cs.txt Normal file
View file

@ -0,0 +1,75 @@
===============================================================================
ALE C# Integration *ale-cs-options*
===============================================================================
mcs *ale-cs-mcs*
The mcs linter calls the mono mcs compiler setting the --parse and -unsafe
flags.
g:ale_cs_mcs_options *g:ale_cs_mcs_options*
*b:ale_cs_mcs_options*
Type: String
Default: `''`
This variable can be changed to modify flags given to mcs. The options
--parse and -unsafe are implicitly set.
===============================================================================
mcsc *ale-cs-mcsc*
The mcsc linter uses the mono mcs compiler to generate a temporary module
target file (-t:module) including all '*.cs' files contained in the
directory by specified by |g:ale_cs_mcsc_source| or |b:ale_cs_mcsc_source|
variable and all sub directories. Currently none can be excluded from
linting. It uses the assembly directories as specified by
|g:ale_cs_mcsc_assembly_path| or |b:ale_cs_mcsc_assembly_path| and selects
the assembly files specified by |g:ale_cs_mcsc_assemblies| or
|b:ale_cs_mcsc_assemblies|. The mcs -unsafe option is set implicitly and has
not to be added using |g:ale_cs_mcsc_options| or |b:ale_cs_mcsc_options|
variable.
g:ale_cs_mcsc_options *g:ale_cs_mcsc_options*
*b:ale_cs_mcsc_options*
Type: |String|
Default: `''`
This variable can be set to set further options for example adding packages
(eg.: -pkg:dotnet) with are not added per default.
g:ale_cs_mcsc_source *g:ale_cs_mcsc_source*
*b:ale_cs_mcsc_source*
Type: |String|
Default: `''`
This variable defines the base path of the directory tree the '*.cs' files
should be included into the compilation of the temporary module. If empty
the current directory is used.
g:ale_cs_mcsc_assembly_path *g:ale_cs_mcsc_assembly_path*
*b:ale_cs_mcsc_assembly_path*
Type: |List|
Default: `[]`
This variable defines a list of absolute or relative path strings pointing
to the location of the assembly files (*.dll) to be considered by mcsc
linter. If the list is not empty the list will be added to the mcsc command
line using the -lib: flag of mcs.
g:ale_cs_mcsc_assemblies *g:ale_cs_mcsc_assemblies*
*b:ale_cs_mcsc_assemblies*
Type: |List|
Default: `[]`
This variable defines a list of assembly files (*.dll) to be considered by
the mono mcs compiler when generating the temporary module. If the list is
not empty the list of assemblies will be added to the mcsc command
line using the -r: flag of mcs. To change the search path mcs uses to
locate the specified assembly files use |g:ale_cs_mcsc_assembly_path| or
|b:ale_cs_mcsc_assembly_path| variables
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: