From 0b4507ed565a53ad884dd9c7a0042daa4c782ae4 Mon Sep 17 00:00:00 2001 From: Martino Pilia Date: Sun, 11 Nov 2018 18:26:37 +0100 Subject: [PATCH 1/3] Add linter for ispc --- README.md | 1 + ale_linters/ispc/ispc.vim | 68 ++++ doc/ale-ispc.txt | 24 ++ doc/ale.txt | 3 + .../test_ispc_ispc_command_callbacks.vader | 27 ++ test/handler/test_ispc_ispc_handler.vader | 347 ++++++++++++++++++ 6 files changed, 470 insertions(+) create mode 100644 ale_linters/ispc/ispc.vim create mode 100644 doc/ale-ispc.txt create mode 100644 test/command_callback/test_ispc_ispc_command_callbacks.vader create mode 100644 test/handler/test_ispc_ispc_handler.vader diff --git a/README.md b/README.md index 4540ac9f..0c96b811 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,7 @@ formatting. | HCL | [terraform-fmt](https://github.com/hashicorp/terraform) | | HTML | [alex](https://github.com/wooorm/alex) !!, [HTMLHint](http://htmlhint.com/), [proselint](http://proselint.com/), [tidy](http://www.html-tidy.org/), [prettier](https://github.com/prettier/prettier), [write-good](https://github.com/btford/write-good) | | Idris | [idris](http://www.idris-lang.org/) | +| ISPC | [ispc](https://ispc.github.io/) | | Java | [checkstyle](http://checkstyle.sourceforge.net), [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html), [google-java-format](https://github.com/google/google-java-format), [PMD](https://pmd.github.io/), [javalsp](https://github.com/georgewfraser/vscode-javac), [uncrustify](https://github.com/uncrustify/uncrustify) | | JavaScript | [eslint](http://eslint.org/), [flow](https://flowtype.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/), [prettier](https://github.com/prettier/prettier), [prettier-eslint](https://github.com/prettier/prettier-eslint-cli), [prettier-standard](https://github.com/sheerun/prettier-standard), [standard](http://standardjs.com/), [xo](https://github.com/sindresorhus/xo) | JSON | [fixjson](https://github.com/rhysd/fixjson), [jsonlint](http://zaa.ch/jsonlint/), [jq](https://stedolan.github.io/jq/), [prettier](https://github.com/prettier/prettier) | diff --git a/ale_linters/ispc/ispc.vim b/ale_linters/ispc/ispc.vim new file mode 100644 index 00000000..283cfdff --- /dev/null +++ b/ale_linters/ispc/ispc.vim @@ -0,0 +1,68 @@ +" Author: Martino Pilia +" Description: Lint ispc files with the Intel(R) SPMD Program Compiler + +call ale#Set('ispc_ispc_executable', 'ispc') +call ale#Set('ispc_ispc_options', '') + +" ISPC has no equivalent of gcc's -iquote argument, so use a -I for headers +" in the same directory. Not perfect, since now local headers are accepted +" by #include<> while they should not, but better than nothing. +function! ale_linters#ispc#ispc#GetCommand(buffer) abort + return '%e ' + \ . '-I ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) + \ . ale#Pad(ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))) + \ . ale#Pad(ale#Var(a:buffer, 'ispc_ispc_options')) . ' -' +endfunction + +" Note that we ignore the two warnings in the beginning of the compiler output +" ('no output file specified' and 'no --target specified'), since they have +" nothing to do with linting. +function! ale_linters#ispc#ispc#Handle(buffer, lines) abort + " Message format: :: : + " As far as I know, can be any of: + " 'error', 'Error', 'fatal error', 'Warning', 'Performance Warning' + let l:re = '\v(.+):([0-9]+):([0-9]+):\s+([^:]+):\s+(.+)\s*' + let l:Trim = {s -> substitute(s, '^\s*\(.\{-}\)\s*$', '\1', '')} + let l:line_count = len(a:lines) + let l:output = [] + + for l:index in range(l:line_count) + let l:match = matchlist(a:lines[l:index], l:re) + + if l:match != [] + let l:text = l:Trim(l:match[5]) + + " The text may continue over multiple lines. + " Look for a full stop, question, or exclamation mark + " ending the text. + " Also, for some reason, 'file not found' messages are on + " one line but not terminated by punctuation. + while match(l:text, '[.?!]\s*$') == -1 + \ && match(l:text, 'file not found') == -1 + \ && l:index < l:line_count - 1 + let l:index += 1 + let l:text .= ' ' . l:Trim(a:lines[l:index]) + endwhile + + call add(l:output, { + \ 'filename': fnamemodify(l:match[1], ':p'), + \ 'bufnr': a:buffer, + \ 'lnum': str2nr(l:match[2]), + \ 'col': str2nr(l:match[3]), + \ 'type': l:match[4] =~? 'error' ? 'E' : 'W', + \ 'text': l:text, + \}) + continue + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('ispc', { +\ 'name': 'ispc', +\ 'output_stream': 'stderr', +\ 'executable_callback': ale#VarFunc('ispc_ispc_executable'), +\ 'command_callback': 'ale_linters#ispc#ispc#GetCommand', +\ 'callback': 'ale_linters#ispc#ispc#Handle', +\}) diff --git a/doc/ale-ispc.txt b/doc/ale-ispc.txt new file mode 100644 index 00000000..bf30e8e3 --- /dev/null +++ b/doc/ale-ispc.txt @@ -0,0 +1,24 @@ +=============================================================================== +ALE ISPC Integration *ale-ispc-options* + + +=============================================================================== +ispc *ale-ispc-ispc* + +g:ale_ispc_ispc_executable *g:ale_ispc_ispc_executable* + *b:ale_ispc_ispc_executable* + Type: |String| + Default: `'ispc'` + + This variable can be changed to use a different executable for ispc. + + +g:ale_ispc_ispc_options *g:ale_ispc_ispc_options* + *b:ale_ispc_ispc_options* + Type: |String| + Default: `''` + + This variable can be changed to modify flags given to ispc. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale.txt b/doc/ale.txt index 85f6b6f8..c610d0d9 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -145,6 +145,8 @@ CONTENTS *ale-contents* write-good..........................|ale-html-write-good| idris.................................|ale-idris-options| idris...............................|ale-idris-idris| + ispc..................................|ale-ispc-options| + ispc................................|ale-ispc-ispc| java..................................|ale-java-options| checkstyle..........................|ale-java-checkstyle| javac...............................|ale-java-javac| @@ -435,6 +437,7 @@ Notes: * HCL: `terraform-fmt` * HTML: `alex`!!, `HTMLHint`, `proselint`, `tidy`, `prettier`, `write-good` * Idris: `idris` +* ISPC: `ispc` * Java: `checkstyle`, `javac`, `google-java-format`, `PMD`, `javalsp`, `uncrustify` * JavaScript: `eslint`, `flow`, `jscs`, `jshint`, `prettier`, `prettier-eslint`, `prettier-standard`, `standard`, `xo` * JSON: `fixjson`, `jsonlint`, `jq`, `prettier` diff --git a/test/command_callback/test_ispc_ispc_command_callbacks.vader b/test/command_callback/test_ispc_ispc_command_callbacks.vader new file mode 100644 index 00000000..e5a0dec2 --- /dev/null +++ b/test/command_callback/test_ispc_ispc_command_callbacks.vader @@ -0,0 +1,27 @@ +Before: + call ale#assert#SetUpLinterTest('ispc', 'ispc') + +After: + call ale#assert#TearDownLinterTest() + +Execute(The executable should be configurable): + AssertLinter 'ispc', + \ ale#Escape('ispc') + \ . ' -I ' . ale#Escape(getcwd()) + \ . ' -' + + let b:ale_ispc_ispc_executable = 'foo' + + AssertLinter 'foo', + \ ale#Escape('foo') + \ . ' -I ' . ale#Escape(getcwd()) + \ . ' -' + +Execute(The options should be configurable): + let g:ale_ispc_ispc_options = '--foo' + + AssertLinter 'ispc', + \ ale#Escape('ispc') + \ . ' -I ' . ale#Escape(getcwd()) + \ . ' --foo' + \ . ' -' diff --git a/test/handler/test_ispc_ispc_handler.vader b/test/handler/test_ispc_ispc_handler.vader new file mode 100644 index 00000000..3fb67277 --- /dev/null +++ b/test/handler/test_ispc_ispc_handler.vader @@ -0,0 +1,347 @@ +Before: + runtime ale_linters/ispc/ispc.vim + +After: + call ale#linter#Reset() + +Execute(The ispc handler should parse input correctly): + AssertEqual + \ [ + \ { + \ 'bufnr': 0, + \ 'lnum': 33, + \ 'col': 14, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected ''int'', expecting '','' or '';''.', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 36, + \ 'col': 5, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected ''for''.', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 40, + \ 'col': 24, + \ 'type': 'E', + \ 'text': 'Undeclared symbol "z_re".', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 40, + \ 'col': 29, + \ 'type': 'E', + \ 'text': 'Undeclared symbol "z_re".', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 40, + \ 'col': 36, + \ 'type': 'E', + \ 'text': 'Undeclared symbol "z_im".', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 40, + \ 'col': 41, + \ 'type': 'E', + \ 'text': 'Undeclared symbol "z_im".', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 41, + \ 'col': 30, + \ 'type': 'E', + \ 'text': 'Undeclared symbol "z_re".', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 41, + \ 'col': 37, + \ 'type': 'E', + \ 'text': 'Undeclared symbol "z_im".', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 42, + \ 'col': 18, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected ''{''.', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 58, + \ 'col': 17, + \ 'type': 'E', + \ 'text': 'Undeclared symbol "y1". Did you mean "i", or "or"?', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 58, + \ 'col': 22, + \ 'type': 'E', + \ 'text': 'Undeclared symbol "y0". Did you mean "i", or "or"?', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 58, + \ 'col': 28, + \ 'type': 'E', + \ 'text': 'Undeclared symbol "height".', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 60, + \ 'col': 5, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected ''for''.', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 71, + \ 'col': 23, + \ 'type': 'E', + \ 'text': 'Undeclared symbol "y0". Did you mean "dy", or "i", or "or"?', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 71, + \ 'col': 28, + \ 'type': 'E', + \ 'text': 'Undeclared symbol "j". Did you mean "i"?', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 73, + \ 'col': 25, + \ 'type': 'E', + \ 'text': 'Undeclared symbol "j". Did you mean "i", or "y"?', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 73, + \ 'col': 29, + \ 'type': 'E', + \ 'text': 'Undeclared symbol "width".', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 74, + \ 'col': 13, + \ 'type': 'E', + \ 'text': 'syntax error, unexpected identifier.', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 51, + \ 'col': 9, + \ 'type': 'E', + \ 'text': '''foobar.h'' file not found', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 79, + \ 'col': 52, + \ 'type': 'W', + \ 'text': 'Modulus operator with varying types is very inefficient.', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 85, + \ 'col': 13, + \ 'type': 'W', + \ 'text': 'Undefined behavior: all program instances are writing to the same location!', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 93, + \ 'col': 19, + \ 'type': 'W', + \ 'text': 'Gather required to load value.', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ { + \ 'bufnr': 0, + \ 'lnum': 93, + \ 'col': 9, + \ 'type': 'W', + \ 'text': 'Scatter required to store value.', + \ 'filename': has('win32') + \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' + \ : '/testplugin/test/handler/mandelbrot.ispc', + \ }, + \ ], + \ ale_linters#ispc#ispc#Handle(0, [ + \ 'Warning: No output file or header file name specified. Program will ', + \ ' be compiled and warnings/errors will be issued, but no output will be ', + \ ' generated. ', + \ 'Warning: No --target specified on command-line. Using default system ', + \ ' target "avx2-i32x8". ', + \ 'mandelbrot.ispc:33:14: Error: syntax error, unexpected ''int'', ', + \ ' expecting '','' or '';''. ', + \ 'static iline int mandel(float c_re, float c_im, int count) {', + \ ' ^^^', + \ '', + \ 'mandelbrot.ispc:36:5: Error: syntax error, unexpected ''for''. ', + \ ' for (i = 0; i < count; ++i) {', + \ ' ^^^', + \ '', + \ 'mandelbrot.ispc:40:24: Error: Undeclared symbol "z_re". ', + \ ' float new_re = z_re*z_re - z_im*z_im;', + \ ' ^^^^', + \ '', + \ 'mandelbrot.ispc:40:29: Error: Undeclared symbol "z_re". ', + \ ' float new_re = z_re*z_re - z_im*z_im;', + \ ' ^^^^', + \ '', + \ 'mandelbrot.ispc:40:36: Error: Undeclared symbol "z_im". ', + \ ' float new_re = z_re*z_re - z_im*z_im;', + \ ' ^^^^', + \ '', + \ 'mandelbrot.ispc:40:41: Error: Undeclared symbol "z_im". ', + \ ' float new_re = z_re*z_re - z_im*z_im;', + \ ' ^^^^', + \ '', + \ 'mandelbrot.ispc:41:30: Error: Undeclared symbol "z_re". ', + \ ' float new_im = 2.f * z_re * z_im;', + \ ' ^^^^', + \ '', + \ 'mandelbrot.ispc:41:37: Error: Undeclared symbol "z_im". ', + \ ' float new_im = 2.f * z_re * z_im;', + \ ' ^^^^', + \ '', + \ 'mandelbrot.ispc:42:18: Error: syntax error, unexpected ''{''. ', + \ ' unmasked {', + \ ' ^', + \ '', + \ 'mandelbrot.ispc:58:17: Error: Undeclared symbol "y1". Did you mean ', + \ ' "i", or "or"? ', + \ ' float dy = (y1 - y0) / height;', + \ ' ^^', + \ '', + \ 'mandelbrot.ispc:58:22: Error: Undeclared symbol "y0". Did you mean ', + \ ' "i", or "or"? ', + \ ' float dy = (y1 - y0) / height;', + \ ' ^^', + \ '', + \ 'mandelbrot.ispc:58:28: Error: Undeclared symbol "height". ', + \ ' float dy = (y1 - y0) / height;', + \ ' ^^^^^^', + \ '', + \ 'mandelbrot.ispc:60:5: Error: syntax error, unexpected ''for''. ', + \ ' for (uniform int j = 0; j < height; j++) {', + \ ' ^^^', + \ '', + \ 'mandelbrot.ispc:71:23: Error: Undeclared symbol "y0". Did you mean ', + \ ' "dy", or "i", or "or"? ', + \ ' float y = y0 + j * dy;', + \ ' ^^', + \ '', + \ 'mandelbrot.ispc:71:28: Error: Undeclared symbol "j". Did you mean ', + \ ' "i"? ', + \ ' float y = y0 + j * dy;', + \ ' ^', + \ '', + \ 'mandelbrot.ispc:73:25: Error: Undeclared symbol "j". Did you mean ', + \ ' "i", or "y"? ', + \ ' int index = j * width + i;', + \ ' ^', + \ '', + \ 'mandelbrot.ispc:73:29: Error: Undeclared symbol "width". ', + \ ' int index = j * width + i;', + \ ' ^^^^^', + \ '', + \ 'mandelbrot.ispc:74:13: Error: syntax error, unexpected ', + \ ' identifier. ', + \ ' output[index] = mandel(x, y, maxIterations);', + \ ' ^^^^^^', + \ '', + \ 'mandelbrot.ispc:51:9: fatal error: ''foobar.h'' file not found', + \ '#include', + \ ' ^~~~~~~~~~', + \ 'mandelbrot.ispc:79:52: Performance Warning: Modulus operator with ', + \ ' varying types is very inefficient. ', + \ ' double x = x0 + i * (dx + epsilon*(k%2)*delta);', + \ ' ^^^', + \ '', + \ 'mandelbrot.ispc:85:13: Warning: Undefined behavior: all program ', + \ ' instances are writing to the same location! ', + \ ' output[index] = (NNN) / sample_size;', + \ ' ^^^^^^^^^^^^^', + \ '', + \ 'mandelbrot.ispc:93:19: Performance Warning: Gather required to load value. ', + \ ' A[i*8] *= A[i*8];', + \ ' ^^^^^^', + \ '', + \ 'mandelbrot.ispc:93:9: Performance Warning: Scatter required to store value. ', + \ ' A[i*8] *= A[i*8];', + \ ' ^^^^^^', + \ '', + \ ]) From 9e8f2b08401af5af83b181a0ca5419937f3fd0de Mon Sep 17 00:00:00 2001 From: Martino Pilia Date: Mon, 12 Nov 2018 00:54:24 +0100 Subject: [PATCH 2/3] Lint ispc on disk to solve include imprecisions --- README.md | 2 +- ale_linters/ispc/ispc.vim | 10 ++++------ doc/ale.txt | 2 +- .../test_ispc_ispc_command_callbacks.vader | 13 +++---------- 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 0c96b811..801d908f 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ formatting. | HCL | [terraform-fmt](https://github.com/hashicorp/terraform) | | HTML | [alex](https://github.com/wooorm/alex) !!, [HTMLHint](http://htmlhint.com/), [proselint](http://proselint.com/), [tidy](http://www.html-tidy.org/), [prettier](https://github.com/prettier/prettier), [write-good](https://github.com/btford/write-good) | | Idris | [idris](http://www.idris-lang.org/) | -| ISPC | [ispc](https://ispc.github.io/) | +| ISPC | [ispc](https://ispc.github.io/) !! | | Java | [checkstyle](http://checkstyle.sourceforge.net), [javac](http://www.oracle.com/technetwork/java/javase/downloads/index.html), [google-java-format](https://github.com/google/google-java-format), [PMD](https://pmd.github.io/), [javalsp](https://github.com/georgewfraser/vscode-javac), [uncrustify](https://github.com/uncrustify/uncrustify) | | JavaScript | [eslint](http://eslint.org/), [flow](https://flowtype.org/), [jscs](http://jscs.info/), [jshint](http://jshint.com/), [prettier](https://github.com/prettier/prettier), [prettier-eslint](https://github.com/prettier/prettier-eslint-cli), [prettier-standard](https://github.com/sheerun/prettier-standard), [standard](http://standardjs.com/), [xo](https://github.com/sindresorhus/xo) | JSON | [fixjson](https://github.com/rhysd/fixjson), [jsonlint](http://zaa.ch/jsonlint/), [jq](https://stedolan.github.io/jq/), [prettier](https://github.com/prettier/prettier) | diff --git a/ale_linters/ispc/ispc.vim b/ale_linters/ispc/ispc.vim index 283cfdff..b5f33f5b 100644 --- a/ale_linters/ispc/ispc.vim +++ b/ale_linters/ispc/ispc.vim @@ -4,14 +4,11 @@ call ale#Set('ispc_ispc_executable', 'ispc') call ale#Set('ispc_ispc_options', '') -" ISPC has no equivalent of gcc's -iquote argument, so use a -I for headers -" in the same directory. Not perfect, since now local headers are accepted -" by #include<> while they should not, but better than nothing. function! ale_linters#ispc#ispc#GetCommand(buffer) abort - return '%e ' - \ . '-I ' . ale#Escape(fnamemodify(bufname(a:buffer), ':p:h')) + return '%e' \ . ale#Pad(ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))) - \ . ale#Pad(ale#Var(a:buffer, 'ispc_ispc_options')) . ' -' + \ . ale#Pad(ale#Var(a:buffer, 'ispc_ispc_options')) + \ . ' %s' endfunction " Note that we ignore the two warnings in the beginning of the compiler output @@ -65,4 +62,5 @@ call ale#linter#Define('ispc', { \ 'executable_callback': ale#VarFunc('ispc_ispc_executable'), \ 'command_callback': 'ale_linters#ispc#ispc#GetCommand', \ 'callback': 'ale_linters#ispc#ispc#Handle', +\ 'lint_file': 1, \}) diff --git a/doc/ale.txt b/doc/ale.txt index c610d0d9..6910ae6f 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -437,7 +437,7 @@ Notes: * HCL: `terraform-fmt` * HTML: `alex`!!, `HTMLHint`, `proselint`, `tidy`, `prettier`, `write-good` * Idris: `idris` -* ISPC: `ispc` +* ISPC: `ispc`!! * Java: `checkstyle`, `javac`, `google-java-format`, `PMD`, `javalsp`, `uncrustify` * JavaScript: `eslint`, `flow`, `jscs`, `jshint`, `prettier`, `prettier-eslint`, `prettier-standard`, `standard`, `xo` * JSON: `fixjson`, `jsonlint`, `jq`, `prettier` diff --git a/test/command_callback/test_ispc_ispc_command_callbacks.vader b/test/command_callback/test_ispc_ispc_command_callbacks.vader index e5a0dec2..012cdee2 100644 --- a/test/command_callback/test_ispc_ispc_command_callbacks.vader +++ b/test/command_callback/test_ispc_ispc_command_callbacks.vader @@ -6,22 +6,15 @@ After: Execute(The executable should be configurable): AssertLinter 'ispc', - \ ale#Escape('ispc') - \ . ' -I ' . ale#Escape(getcwd()) - \ . ' -' + \ ale#Escape('ispc') . ' %s' let b:ale_ispc_ispc_executable = 'foo' AssertLinter 'foo', - \ ale#Escape('foo') - \ . ' -I ' . ale#Escape(getcwd()) - \ . ' -' + \ ale#Escape('foo') . ' %s' Execute(The options should be configurable): let g:ale_ispc_ispc_options = '--foo' AssertLinter 'ispc', - \ ale#Escape('ispc') - \ . ' -I ' . ale#Escape(getcwd()) - \ . ' --foo' - \ . ' -' + \ ale#Escape('ispc') . ' --foo' . ' %s' From 66212966dd39dd721af6a2aa683ed5a93c293c77 Mon Sep 17 00:00:00 2001 From: Martino Pilia Date: Wed, 21 Nov 2018 10:40:07 +0100 Subject: [PATCH 3/3] Add --nowrap to ispc options --- ale_linters/ispc/ispc.vim | 43 +-- .../test_ispc_ispc_command_callbacks.vader | 6 +- test/handler/test_ispc_ispc_handler.vader | 273 +----------------- 3 files changed, 22 insertions(+), 300 deletions(-) diff --git a/ale_linters/ispc/ispc.vim b/ale_linters/ispc/ispc.vim index b5f33f5b..de7ceafa 100644 --- a/ale_linters/ispc/ispc.vim +++ b/ale_linters/ispc/ispc.vim @@ -5,7 +5,8 @@ call ale#Set('ispc_ispc_executable', 'ispc') call ale#Set('ispc_ispc_options', '') function! ale_linters#ispc#ispc#GetCommand(buffer) abort - return '%e' + " --nowrap: do not wrap message lines + return '%e --nowrap' \ . ale#Pad(ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))) \ . ale#Pad(ale#Var(a:buffer, 'ispc_ispc_options')) \ . ' %s' @@ -18,39 +19,17 @@ function! ale_linters#ispc#ispc#Handle(buffer, lines) abort " Message format: :: : " As far as I know, can be any of: " 'error', 'Error', 'fatal error', 'Warning', 'Performance Warning' - let l:re = '\v(.+):([0-9]+):([0-9]+):\s+([^:]+):\s+(.+)\s*' - let l:Trim = {s -> substitute(s, '^\s*\(.\{-}\)\s*$', '\1', '')} - let l:line_count = len(a:lines) + let l:re = '\v.+:([0-9]+):([0-9]+):\s+([^:]+):\s+(.+)' let l:output = [] - for l:index in range(l:line_count) - let l:match = matchlist(a:lines[l:index], l:re) - - if l:match != [] - let l:text = l:Trim(l:match[5]) - - " The text may continue over multiple lines. - " Look for a full stop, question, or exclamation mark - " ending the text. - " Also, for some reason, 'file not found' messages are on - " one line but not terminated by punctuation. - while match(l:text, '[.?!]\s*$') == -1 - \ && match(l:text, 'file not found') == -1 - \ && l:index < l:line_count - 1 - let l:index += 1 - let l:text .= ' ' . l:Trim(a:lines[l:index]) - endwhile - - call add(l:output, { - \ 'filename': fnamemodify(l:match[1], ':p'), - \ 'bufnr': a:buffer, - \ 'lnum': str2nr(l:match[2]), - \ 'col': str2nr(l:match[3]), - \ 'type': l:match[4] =~? 'error' ? 'E' : 'W', - \ 'text': l:text, - \}) - continue - endif + for l:match in ale#util#GetMatches(a:lines, l:re) + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': str2nr(l:match[1]), + \ 'col': str2nr(l:match[2]), + \ 'type': l:match[3] =~? 'error' ? 'E' : 'W', + \ 'text': l:match[4], + \}) endfor return l:output diff --git a/test/command_callback/test_ispc_ispc_command_callbacks.vader b/test/command_callback/test_ispc_ispc_command_callbacks.vader index 012cdee2..f1aeb2f8 100644 --- a/test/command_callback/test_ispc_ispc_command_callbacks.vader +++ b/test/command_callback/test_ispc_ispc_command_callbacks.vader @@ -6,15 +6,15 @@ After: Execute(The executable should be configurable): AssertLinter 'ispc', - \ ale#Escape('ispc') . ' %s' + \ ale#Escape('ispc') . ' --nowrap %s' let b:ale_ispc_ispc_executable = 'foo' AssertLinter 'foo', - \ ale#Escape('foo') . ' %s' + \ ale#Escape('foo') . ' --nowrap %s' Execute(The options should be configurable): let g:ale_ispc_ispc_options = '--foo' AssertLinter 'ispc', - \ ale#Escape('ispc') . ' --foo' . ' %s' + \ ale#Escape('ispc') . ' --nowrap --foo' . ' %s' diff --git a/test/handler/test_ispc_ispc_handler.vader b/test/handler/test_ispc_ispc_handler.vader index 3fb67277..619773fe 100644 --- a/test/handler/test_ispc_ispc_handler.vader +++ b/test/handler/test_ispc_ispc_handler.vader @@ -13,9 +13,6 @@ Execute(The ispc handler should parse input correctly): \ 'col': 14, \ 'type': 'E', \ 'text': 'syntax error, unexpected ''int'', expecting '','' or '';''.', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', \ }, \ { \ 'bufnr': 0, @@ -23,169 +20,6 @@ Execute(The ispc handler should parse input correctly): \ 'col': 5, \ 'type': 'E', \ 'text': 'syntax error, unexpected ''for''.', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 40, - \ 'col': 24, - \ 'type': 'E', - \ 'text': 'Undeclared symbol "z_re".', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 40, - \ 'col': 29, - \ 'type': 'E', - \ 'text': 'Undeclared symbol "z_re".', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 40, - \ 'col': 36, - \ 'type': 'E', - \ 'text': 'Undeclared symbol "z_im".', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 40, - \ 'col': 41, - \ 'type': 'E', - \ 'text': 'Undeclared symbol "z_im".', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 41, - \ 'col': 30, - \ 'type': 'E', - \ 'text': 'Undeclared symbol "z_re".', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 41, - \ 'col': 37, - \ 'type': 'E', - \ 'text': 'Undeclared symbol "z_im".', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 42, - \ 'col': 18, - \ 'type': 'E', - \ 'text': 'syntax error, unexpected ''{''.', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 58, - \ 'col': 17, - \ 'type': 'E', - \ 'text': 'Undeclared symbol "y1". Did you mean "i", or "or"?', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 58, - \ 'col': 22, - \ 'type': 'E', - \ 'text': 'Undeclared symbol "y0". Did you mean "i", or "or"?', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 58, - \ 'col': 28, - \ 'type': 'E', - \ 'text': 'Undeclared symbol "height".', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 60, - \ 'col': 5, - \ 'type': 'E', - \ 'text': 'syntax error, unexpected ''for''.', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 71, - \ 'col': 23, - \ 'type': 'E', - \ 'text': 'Undeclared symbol "y0". Did you mean "dy", or "i", or "or"?', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 71, - \ 'col': 28, - \ 'type': 'E', - \ 'text': 'Undeclared symbol "j". Did you mean "i"?', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 73, - \ 'col': 25, - \ 'type': 'E', - \ 'text': 'Undeclared symbol "j". Did you mean "i", or "y"?', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 73, - \ 'col': 29, - \ 'type': 'E', - \ 'text': 'Undeclared symbol "width".', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', - \ }, - \ { - \ 'bufnr': 0, - \ 'lnum': 74, - \ 'col': 13, - \ 'type': 'E', - \ 'text': 'syntax error, unexpected identifier.', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', \ }, \ { \ 'bufnr': 0, @@ -193,9 +27,6 @@ Execute(The ispc handler should parse input correctly): \ 'col': 9, \ 'type': 'E', \ 'text': '''foobar.h'' file not found', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', \ }, \ { \ 'bufnr': 0, @@ -203,9 +34,6 @@ Execute(The ispc handler should parse input correctly): \ 'col': 52, \ 'type': 'W', \ 'text': 'Modulus operator with varying types is very inefficient.', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', \ }, \ { \ 'bufnr': 0, @@ -213,9 +41,6 @@ Execute(The ispc handler should parse input correctly): \ 'col': 13, \ 'type': 'W', \ 'text': 'Undefined behavior: all program instances are writing to the same location!', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', \ }, \ { \ 'bufnr': 0, @@ -223,9 +48,6 @@ Execute(The ispc handler should parse input correctly): \ 'col': 19, \ 'type': 'W', \ 'text': 'Gather required to load value.', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', \ }, \ { \ 'bufnr': 0, @@ -233,114 +55,35 @@ Execute(The ispc handler should parse input correctly): \ 'col': 9, \ 'type': 'W', \ 'text': 'Scatter required to store value.', - \ 'filename': has('win32') - \ ? 'C:\testplugin\test\handler\mandelbrot.ispc' - \ : '/testplugin/test/handler/mandelbrot.ispc', \ }, \ ], \ ale_linters#ispc#ispc#Handle(0, [ - \ 'Warning: No output file or header file name specified. Program will ', - \ ' be compiled and warnings/errors will be issued, but no output will be ', - \ ' generated. ', - \ 'Warning: No --target specified on command-line. Using default system ', - \ ' target "avx2-i32x8". ', - \ 'mandelbrot.ispc:33:14: Error: syntax error, unexpected ''int'', ', - \ ' expecting '','' or '';''. ', + \ 'Warning: No output file or header file name specified. Program will be compiled and warnings/errors will be issued, but no output will be generated. ', + \ 'Warning: No --target specified on command-line. Using default system target "avx2-i32x8".', + \ 'mandelbrot.ispc:33:14: Error: syntax error, unexpected ''int'', expecting '','' or '';''.', \ 'static iline int mandel(float c_re, float c_im, int count) {', \ ' ^^^', \ '', - \ 'mandelbrot.ispc:36:5: Error: syntax error, unexpected ''for''. ', + \ 'mandelbrot.ispc:36:5: Error: syntax error, unexpected ''for''.', \ ' for (i = 0; i < count; ++i) {', \ ' ^^^', \ '', - \ 'mandelbrot.ispc:40:24: Error: Undeclared symbol "z_re". ', - \ ' float new_re = z_re*z_re - z_im*z_im;', - \ ' ^^^^', - \ '', - \ 'mandelbrot.ispc:40:29: Error: Undeclared symbol "z_re". ', - \ ' float new_re = z_re*z_re - z_im*z_im;', - \ ' ^^^^', - \ '', - \ 'mandelbrot.ispc:40:36: Error: Undeclared symbol "z_im". ', - \ ' float new_re = z_re*z_re - z_im*z_im;', - \ ' ^^^^', - \ '', - \ 'mandelbrot.ispc:40:41: Error: Undeclared symbol "z_im". ', - \ ' float new_re = z_re*z_re - z_im*z_im;', - \ ' ^^^^', - \ '', - \ 'mandelbrot.ispc:41:30: Error: Undeclared symbol "z_re". ', - \ ' float new_im = 2.f * z_re * z_im;', - \ ' ^^^^', - \ '', - \ 'mandelbrot.ispc:41:37: Error: Undeclared symbol "z_im". ', - \ ' float new_im = 2.f * z_re * z_im;', - \ ' ^^^^', - \ '', - \ 'mandelbrot.ispc:42:18: Error: syntax error, unexpected ''{''. ', - \ ' unmasked {', - \ ' ^', - \ '', - \ 'mandelbrot.ispc:58:17: Error: Undeclared symbol "y1". Did you mean ', - \ ' "i", or "or"? ', - \ ' float dy = (y1 - y0) / height;', - \ ' ^^', - \ '', - \ 'mandelbrot.ispc:58:22: Error: Undeclared symbol "y0". Did you mean ', - \ ' "i", or "or"? ', - \ ' float dy = (y1 - y0) / height;', - \ ' ^^', - \ '', - \ 'mandelbrot.ispc:58:28: Error: Undeclared symbol "height". ', - \ ' float dy = (y1 - y0) / height;', - \ ' ^^^^^^', - \ '', - \ 'mandelbrot.ispc:60:5: Error: syntax error, unexpected ''for''. ', - \ ' for (uniform int j = 0; j < height; j++) {', - \ ' ^^^', - \ '', - \ 'mandelbrot.ispc:71:23: Error: Undeclared symbol "y0". Did you mean ', - \ ' "dy", or "i", or "or"? ', - \ ' float y = y0 + j * dy;', - \ ' ^^', - \ '', - \ 'mandelbrot.ispc:71:28: Error: Undeclared symbol "j". Did you mean ', - \ ' "i"? ', - \ ' float y = y0 + j * dy;', - \ ' ^', - \ '', - \ 'mandelbrot.ispc:73:25: Error: Undeclared symbol "j". Did you mean ', - \ ' "i", or "y"? ', - \ ' int index = j * width + i;', - \ ' ^', - \ '', - \ 'mandelbrot.ispc:73:29: Error: Undeclared symbol "width". ', - \ ' int index = j * width + i;', - \ ' ^^^^^', - \ '', - \ 'mandelbrot.ispc:74:13: Error: syntax error, unexpected ', - \ ' identifier. ', - \ ' output[index] = mandel(x, y, maxIterations);', - \ ' ^^^^^^', - \ '', \ 'mandelbrot.ispc:51:9: fatal error: ''foobar.h'' file not found', \ '#include', \ ' ^~~~~~~~~~', - \ 'mandelbrot.ispc:79:52: Performance Warning: Modulus operator with ', - \ ' varying types is very inefficient. ', + \ 'mandelbrot.ispc:79:52: Performance Warning: Modulus operator with varying types is very inefficient.', \ ' double x = x0 + i * (dx + epsilon*(k%2)*delta);', \ ' ^^^', \ '', - \ 'mandelbrot.ispc:85:13: Warning: Undefined behavior: all program ', - \ ' instances are writing to the same location! ', + \ 'mandelbrot.ispc:85:13: Warning: Undefined behavior: all program instances are writing to the same location!', \ ' output[index] = (NNN) / sample_size;', \ ' ^^^^^^^^^^^^^', \ '', - \ 'mandelbrot.ispc:93:19: Performance Warning: Gather required to load value. ', + \ 'mandelbrot.ispc:93:19: Performance Warning: Gather required to load value.', \ ' A[i*8] *= A[i*8];', \ ' ^^^^^^', \ '', - \ 'mandelbrot.ispc:93:9: Performance Warning: Scatter required to store value. ', + \ 'mandelbrot.ispc:93:9: Performance Warning: Scatter required to store value.', \ ' A[i*8] *= A[i*8];', \ ' ^^^^^^', \ '',