patch 9.1.0967: SpotBugs compiler setup can be further improved

Problem:  SpotBugs compiler can be further improved
Solution: Introduce event-driven primitives for SpotBugs
          (Aliaksei Budavei)

closes: #16258

Signed-off-by: Aliaksei Budavei <0x000c70@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Aliaksei Budavei
2024-12-27 16:46:36 +01:00
committed by Christian Brabandt
parent b7f19a5459
commit 2e252474c4
5 changed files with 173 additions and 9 deletions

View File

@ -1,7 +1,7 @@
" Vim compiler file
" Compiler: Spotbugs (Java static checker; needs javac compiled classes)
" Maintainer: @konfekt and @zzzyxwvut
" Last Change: 2024 Dec 14
" Maintainers: @konfekt and @zzzyxwvut
" Last Change: 2024 Dec 20
if exists('g:current_compiler') || bufname() !~# '\.java\=$' || wordcount().chars < 9
finish

View File

@ -1,4 +1,4 @@
*quickfix.txt* For Vim version 9.1. Last change: 2024 Dec 16
*quickfix.txt* For Vim version 9.1. Last change: 2024 Dec 27
VIM REFERENCE MANUAL by Bram Moolenaar
@ -1424,6 +1424,70 @@ of |:make|, and assigning its |Funcref| to the selected key. For example:
\ function('GenericPostCompilerCommand'),
\ }
When "PostCompilerAction" is available, "PostCompilerActionExecutor" is also
supported. Its value must be a Funcref pointing to a function that always
declares a single parameter of type string and decides whether |:execute| can
be dispatched on its argument, containing a pending post-compiler action,
after ascertaining the current status of |:cc| (or |:ll|): >vim
function! GenericPostCompilerActionExecutor(action) abort
try
cc
catch /\<E42:/
execute a:action
endtry
endfunction
Complementary, some or all of the available "Pre*Action"s (or "*Pre*Command"s)
may run `:doautocmd java_spotbugs_post User` in their implementations before
|:make| (or its equivalent) to define a once-only |ShellCmdPost| `:autocmd`
that will arrange for "PostCompilerActionExecutor" to be invoked; and then run
`:doautocmd java_spotbugs_post ShellCmdPost` to consume this event: >vim
function! GenericPreCompilerCommand(arguments) abort
if !exists('g:spotbugs_compilation_done')
doautocmd java_spotbugs_post User
execute 'make ' . a:arguments
" only run doautocmd when :make was synchronous
" see note below
doautocmd java_spotbugs_post ShellCmdPost " XXX: (a)
let g:spotbugs_compilation_done = 1
else
cc
endif
endfunction
function! GenericPreCompilerTestCommand(arguments) abort
if !exists('g:spotbugs_test_compilation_done')
doautocmd java_spotbugs_post User
execute 'make ' . a:arguments
" only run doautocmd when :make was synchronous
" see note below
doautocmd java_spotbugs_post ShellCmdPost " XXX: (b)
let g:spotbugs_test_compilation_done = 1
else
cc
endif
endfunction
let g:spotbugs_properties = {
\ 'compiler': 'maven',
\ 'DefaultPreCompilerCommand':
\ function('GenericPreCompilerCommand'),
\ 'DefaultPreCompilerTestCommand':
\ function('GenericPreCompilerTestCommand'),
\ 'PostCompilerActionExecutor':
\ function('GenericPostCompilerActionExecutor'),
\ }
If a command equivalent of `:make` is capable of asynchronous execution and
consuming `ShellCmdPost` events, `:doautocmd java_spotbugs_post ShellCmdPost`
must be removed from such "*Action" (or "*Command") implementations (i.e. the
lines `(a)` and `(b)` in the listed examples) to retain a sequential order for
non-blocking execution, and any notification (see below) must be suppressed.
A `ShellCmdPost` `:autocmd` can be associated with any |:augroup| by assigning
its name to the "augroupForPostCompilerAction" key.
When default actions are not suited to a desired workflow, proceed by writing
arbitrary functions yourself and matching their Funcrefs to the supported
keys: "PreCompilerAction", "PreCompilerTestAction", and "PostCompilerAction".

View File

@ -3,7 +3,7 @@
" Maintainer: Aliaksei Budavei <0x000c70 AT gmail DOT com>
" Former Maintainer: Dan Sharp
" Repository: https://github.com/zzzyxwvut/java-vim.git
" Last Change: 2024 Dec 16
" Last Change: 2024 Dec 25
" 2024 Jan 14 by Vim Project (browsefilter)
" 2024 May 23 by Riley Bruins <ribru17@gmail.com> ('commentstring')
@ -113,7 +113,7 @@ if (!empty(get(g:, 'spotbugs_properties', {})) ||
endfunction
" Work around ":bar"s and ":autocmd"s.
function! s:ExecuteActionOnce(cleanup_cmd, action_cmd) abort
function! JavaFileTypeExecuteActionOnce(cleanup_cmd, action_cmd) abort
try
execute a:cleanup_cmd
finally
@ -285,7 +285,7 @@ if (!empty(get(g:, 'spotbugs_properties', {})) ||
for s:action in s:actions
if has_key(s:action, 'once')
execute printf('autocmd java_spotbugs %s <buffer> ' .
\ 'call s:ExecuteActionOnce(%s, %s)',
\ 'call JavaFileTypeExecuteActionOnce(%s, %s)',
\ s:action.event,
\ string(printf('autocmd! java_spotbugs %s <buffer>',
\ s:action.event)),
@ -297,7 +297,41 @@ if (!empty(get(g:, 'spotbugs_properties', {})) ||
endif
endfor
unlet! s:action s:actions s:idx s:dispatcher
if s:SpotBugsHasProperty('PostCompilerActionExecutor') &&
\ (s:request == 7 || s:request == 6 ||
\ s:request == 5 || s:request == 4)
let s:augroup = s:SpotBugsGetProperty(
\ 'augroupForPostCompilerAction',
\ 'java_spotbugs_post')
let s:augroup = !empty(s:augroup) ? s:augroup : 'java_spotbugs_post'
for s:candidate in ['java_spotbugs_post', s:augroup]
if !exists("#" . s:candidate)
execute printf('augroup %s | augroup END', s:candidate)
endif
endfor
silent! autocmd! java_spotbugs_post User <buffer>
" Define a User ":autocmd" to define a once-only ShellCmdPost
" ":autocmd" that will invoke "PostCompilerActionExecutor" and let
" it decide whether to proceed with ":compiler spotbugs" etc.; and
" seek explicit synchronisation with ":doautocmd ShellCmdPost" by
" omitting "nested" for "java_spotbugs_post" and "java_spotbugs".
execute printf('autocmd java_spotbugs_post User <buffer> ' .
\ 'call JavaFileTypeExecuteActionOnce(%s, %s)',
\ string(printf('autocmd! %s ShellCmdPost <buffer>', s:augroup)),
\ string(printf('autocmd %s ShellCmdPost <buffer> ' .
\ 'call JavaFileTypeExecuteActionOnce(%s, %s)',
\ s:augroup,
\ string(printf('autocmd! %s ShellCmdPost <buffer>', s:augroup)),
\ string(printf('call call(%s, [%s])',
\ string(s:SpotBugsGetProperties().PostCompilerActionExecutor),
\ string(printf('compiler spotbugs | call call(%s, [])',
\ string(s:SpotBugsGetProperties().PostCompilerAction))))))))
endif
unlet! s:candidate s:augroup s:action s:actions s:idx s:dispatcher
endif
delfunction s:SpotBugsGetProperties
@ -310,9 +344,11 @@ function! JavaFileTypeCleanUp() abort
setlocal suffixes< suffixesadd< formatoptions< comments< commentstring< path< includeexpr<
unlet! b:browsefilter
" The concatenated removals may be misparsed as a User autocmd.
" The concatenated ":autocmd" removals may be misparsed as an ":autocmd".
" A _once-only_ ShellCmdPost ":autocmd" is always a call-site definition.
silent! autocmd! java_spotbugs User <buffer>
silent! autocmd! java_spotbugs Syntax <buffer>
silent! autocmd! java_spotbugs_post User <buffer>
endfunction
" Undo the stuff we changed.