From cde50f109105109697c9d2c0e76b9f42d223bbb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xristoph=20Hinterm=C3=BCller?= Date: Mon, 25 Sep 2017 12:54:50 +0200 Subject: [PATCH] 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. --- ale_linters/cs/mcsc.vim | 86 +++++++++++++++++++++++++++++++++++++++++ doc/ale-cs.txt | 75 +++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 ale_linters/cs/mcsc.vim create mode 100644 doc/ale-cs.txt diff --git a/ale_linters/cs/mcsc.vim b/ale_linters/cs/mcsc.vim new file mode 100644 index 00000000..70dc4ab6 --- /dev/null +++ b/ale_linters/cs/mcsc.vim @@ -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 +\}) diff --git a/doc/ale-cs.txt b/doc/ale-cs.txt new file mode 100644 index 00000000..357d7387 --- /dev/null +++ b/doc/ale-cs.txt @@ -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: