Added phpstan linter for php. (#772)

* Added phpstan linter for php.
This commit is contained in:
Ardis 2017-07-16 16:04:25 +02:00 committed by w0rp
parent 4fa66ab627
commit 7d174b0056
5 changed files with 175 additions and 2 deletions

View File

@ -98,7 +98,7 @@ name. That seems to be the fairest way to arrange this table.
| Objective-C++ | [clang](http://clang.llvm.org/) | | Objective-C++ | [clang](http://clang.llvm.org/) |
| OCaml | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-integration-ocaml-merlin` for configuration instructions | OCaml | [merlin](https://github.com/the-lambda-church/merlin) see `:help ale-integration-ocaml-merlin` for configuration instructions
| Perl | [perl -c](https://perl.org/), [perl-critic](https://metacpan.org/pod/Perl::Critic) | | Perl | [perl -c](https://perl.org/), [perl-critic](https://metacpan.org/pod/Perl::Critic) |
| PHP | [hack](http://hacklang.org/), [php -l](https://secure.php.net/), [phpcs](https://github.com/squizlabs/PHP_CodeSniffer), [phpmd](https://phpmd.org) | | PHP | [hack](http://hacklang.org/), [php -l](https://secure.php.net/), [phpcs](https://github.com/squizlabs/PHP_CodeSniffer), [phpmd](https://phpmd.org), [phpstan](https://github.com/phpstan/phpstan) |
| Pod | [proselint](http://proselint.com/)| | Pod | [proselint](http://proselint.com/)|
| Pug | [pug-lint](https://github.com/pugjs/pug-lint) | | Pug | [pug-lint](https://github.com/pugjs/pug-lint) |
| Puppet | [puppet](https://puppet.com), [puppet-lint](https://puppet-lint.com) | | Puppet | [puppet](https://puppet.com), [puppet-lint](https://puppet-lint.com) |

View File

@ -0,0 +1,40 @@
" Author: medains <https://github.com/medains>, ardis <https://github.com/ardisdreelath>
" Description: phpstan for PHP files
" Set to change the ruleset
let g:ale_php_phpstan_executable = get(g:, 'ale_php_phpstan_executable', 'phpstan')
let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '4')
function! ale_linters#php#phpstan#GetCommand(buffer) abort
return ale#Var(a:buffer, 'php_phpstan_executable')
\ . ' analyze -l'
\ . ale#Var(a:buffer, 'php_phpstan_level')
\ . ' --errorFormat raw'
\ . ' %s'
endfunction
function! ale_linters#php#phpstan#Handle(buffer, lines) abort
" Matches against lines like the following:
"
" filename.php:15:message
" C:\folder\filename.php:15:message
let l:pattern = '^\([a-zA-Z]:\)\?[^:]\+:\(\d\+\):\(.*\)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': l:match[2] + 0,
\ 'text': l:match[3],
\ 'type': 'W',
\})
endfor
return l:output
endfunction
call ale#linter#Define('php', {
\ 'name': 'phpstan',
\ 'executable': 'phpstan',
\ 'command_callback': 'ale_linters#php#phpstan#GetCommand',
\ 'callback': 'ale_linters#php#phpstan#Handle',
\})

View File

@ -43,5 +43,24 @@ g:ale_php_phpmd_ruleset *g:ale_php_phpmd_ruleset*
the available phpmd rulesets the available phpmd rulesets
------------------------------------------------------------------------------
phpstan *ale-php-stan*
g:ale_php_phpstan_executable *g:ale_php_phpstan_executable*
*b:ale_php_phpstan_executable*
Type: |String|
Default: `'phpstan'`
This variable sets executable used for phpstan.
g:ale_php_phpstan_level *g:ale_php_phpstan_level*
*b:ale_php_phpstan_level*
Type: |Number|
Default: `4`
This variable controls the rule levels. 0 is the loosest and 4 is the
strictest.
=============================================================================== ===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@ -74,6 +74,7 @@ CONTENTS *ale-contents*
php...................................|ale-php-options| php...................................|ale-php-options|
phpcs...............................|ale-php-phpcs| phpcs...............................|ale-php-phpcs|
phpmd...............................|ale-php-phpmd| phpmd...............................|ale-php-phpmd|
phpstan.............................|ale-php-phpstan|
pug...................................|ale-pug-options| pug...................................|ale-pug-options|
puglint.............................|ale-pug-puglint| puglint.............................|ale-pug-puglint|
python................................|ale-python-options| python................................|ale-python-options|
@ -195,7 +196,7 @@ The following languages and tools are supported.
* Objective-C++: 'clang' * Objective-C++: 'clang'
* OCaml: 'merlin' (see |ale-linter-integration-ocaml-merlin|) * OCaml: 'merlin' (see |ale-linter-integration-ocaml-merlin|)
* Perl: 'perl' (-c flag), 'perlcritic' * Perl: 'perl' (-c flag), 'perlcritic'
* PHP: 'hack', 'php' (-l flag), 'phpcs', 'phpmd' * PHP: 'hack', 'php' (-l flag), 'phpcs', 'phpmd', 'phpstan'
* Pod: 'proselint' * Pod: 'proselint'
* Pug: 'pug-lint' * Pug: 'pug-lint'
* Puppet: 'puppet', 'puppet-lint' * Puppet: 'puppet', 'puppet-lint'

View File

@ -0,0 +1,113 @@
Before:
Save g:ale_php_phpstan_executable
Save g:ale_php_phpstan_level
let g:ale_php_phpstan_executable = 'phpstan_test'
call ale#test#SetDirectory('/testplugin/test')
runtime ale_linters/php/phpstan.vim
After:
Restore
call ale#test#RestoreDirectory()
call ale#linter#Reset()
Execute(project with level set to 3):
call ale#test#SetFilename('phpstan-test-files/foo/test.php')
let g:ale_php_phpstan_level = 3
AssertEqual
\ 'phpstan_test analyze -l3 --errorFormat raw %s',
\ ale_linters#php#phpstan#GetCommand(bufnr(''))
Execute(project with default level):
call ale#test#SetFilename('phpstan-test-files/foo/test.php')
AssertEqual
\ 'phpstan_test analyze -l4 --errorFormat raw %s',
\ ale_linters#php#phpstan#GetCommand(bufnr(''))
Execute(parse output without errors):
call ale#test#SetFilename('phpstan-test-files/foo/test.php')
AssertEqual
\ [],
\ ale_linters#php#phpstan#Handle(bufnr(''), [" 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%"])
Execute(parse output with one error):
call ale#test#SetFilename('phpstan-test-files/foo/test.php')
AssertEqual
\ [
\ {
\ 'lnum': 9,
\ 'text': 'Access to an undefined property Test::$var.',
\ 'type': 'W'
\ }
\ ],
\ ale_linters#php#phpstan#Handle(bufnr(''), [
\ ' 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%',
\ 'phpstan-test-files/foo/test.php:9:Access to an undefined property Test::$var.',
\])
Execute(parse output with three errors):
call ale#test#SetFilename('phpstan-test-files/foo/test.php')
AssertEqual
\ [
\ {
\ 'lnum': 9,
\ 'text': 'Call to method format() on an unknown class DateTimeImutable.',
\ 'type': 'W'
\ },
\ {
\ 'lnum': 16,
\ 'text': 'Sample message.',
\ 'type': 'W'
\ },
\ {
\ 'lnum': 192,
\ 'text': 'Invalid command testCommand.',
\ 'type': 'W'
\ }
\ ],
\ ale_linters#php#phpstan#Handle(bufnr(''), [
\ ' 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%',
\ 'phpstan-test-files/foo/test.php:9:Call to method format() on an unknown class DateTimeImutable.',
\ 'phpstan-test-files/foo/test.php:16:Sample message.',
\ 'phpstan-test-files/foo/test.php:192:Invalid command testCommand.',
\])
Execute(parse output for windows filesystem):
call ale#test#SetFilename('phpstan-test-files/foo/test.php')
AssertEqual
\ [
\ {
\ 'lnum': 9,
\ 'text': 'Access to an undefined property Test::$var.',
\ 'type': 'W'
\ }
\ ],
\ ale_linters#php#phpstan#Handle(bufnr(''), [
\ ' 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%',
\ 'D:\phpstan-test-files\foo\test.php:9:Access to an undefined property Test::$var.',
\])
Execute(parse output for not php file):
call ale#test#SetFilename('phpstan-test-files/test.inc')
AssertEqual
\ [
\ {
\ 'lnum': 9,
\ 'text': 'Access to an undefined property Test::$var.',
\ 'type': 'W'
\ }
\ ],
\ ale_linters#php#phpstan#Handle(bufnr(''), [
\ ' 1/1 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%',
\ '/phpstan-test-files/foo/test.inc:9:Access to an undefined property Test::$var.',
\])