patch 9.1.0967: SpotBugs compiler setup can be further improved

Commit: 
https://github.com/vim/vim/commit/2e252474c4df5018b9819d86ebb70bf3b1b1a1af
Author: Aliaksei Budavei <0x000...@gmail.com>
Date:   Fri Dec 27 16:46:36 2024 +0100

    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 <0x000...@gmail.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/compiler/spotbugs.vim b/runtime/compiler/spotbugs.vim
index 10d164b6a..8ed45f8ee 100644
--- a/runtime/compiler/spotbugs.vim
+++ b/runtime/compiler/spotbugs.vim
@@ -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
diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt
index 1cd075f3e..b6d79507f 100644
--- a/runtime/doc/quickfix.txt
+++ b/runtime/doc/quickfix.txt
@@ -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".
diff --git a/runtime/ftplugin/java.vim b/runtime/ftplugin/java.vim
index 0fa773335..cfd25bce6 100644
--- a/runtime/ftplugin/java.vim
+++ b/runtime/ftplugin/java.vim
@@ -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 <ribr...@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.
diff --git a/src/testdir/test_compiler.vim b/src/testdir/test_compiler.vim
index 14a1fa6a1..d62a4ee3f 100644
--- a/src/testdir/test_compiler.vim
+++ b/src/testdir/test_compiler.vim
@@ -405,12 +405,22 @@ func Test_compiler_spotbugs_properties()
   endfunc
   defer execute('delfunction g:SpotBugsPostCommand')
 
+  func! g:SpotBugsPostCompilerActionExecutor(action) abort
+    try
+      " XXX: Notify the spotbugs compiler about success or failure.
+      cc
+    catch /\<E42:/
+      execute a:action
+    endtry
+  endfunc
+  defer execute('delfunction g:SpotBugsPostCompilerActionExecutor')
+
   " TEST INTEGRATION WITH A SUPPORTED COMPILER PLUGIN.
   if filereadable($VIMRUNTIME .. '/compiler/maven.vim')
     if !executable('mvn')
       if has('win32')
         " This is what ":help executable()" suggests.
-        call writefile([], 'Xspotbugs/mvn.exe')
+        call writefile([], 'Xspotbugs/mvn.cmd')
       else
         let $PATH = 'Xspotbugs:' .. $PATH
         call writefile([], 'Xspotbugs/mvn')
@@ -592,6 +602,8 @@ func Test_compiler_spotbugs_properties()
         \ 'DefaultPreCompilerTestCommand': 
function('g:SpotBugsPreTestCommand'),
         \ 'DefaultPreCompilerCommand': function('g:SpotBugsPreCommand'),
         \ 'DefaultPostCompilerCommand': function('g:SpotBugsPostCommand'),
+        \ 'PostCompilerActionExecutor': 
function('g:SpotBugsPostCompilerActionExecutor'),
+        \ 'augroupForPostCompilerAction': 'java_spotbugs_test',
         \ 'sourceDirPath': ['Xspotbugs/src'],
         \ 'classDirPath': ['Xspotbugs/src'],
         \ 'testSourceDirPath': ['tests'],
@@ -638,6 +650,56 @@ func Test_compiler_spotbugs_properties()
       call assert_match('^spotbugs\s', &l:makeprg)
     endif
 
+    setlocal makeprg=
+    let s:spotbugs_results.preActionDone = 0
+    let s:spotbugs_results.preTestActionOtherDone = 0
+    let s:spotbugs_results.preTestLocalActionDone = 0
+    let s:spotbugs_results.postActionDone = 0
+    let s:spotbugs_results.preCommandArguments = ''
+    let s:spotbugs_results.preTestCommandArguments = ''
+    let s:spotbugs_results.postCommandArguments = ''
+
+    " When "PostCompilerActionExecutor", "Pre*Action" and/or "Pre*TestAction",
+    " and "Post*Action" are available, "#java_spotbugs_post" must be defined.
+    call assert_true(exists('#java_spotbugs_post'))
+    call assert_true(exists('#java_spotbugs_post#User'))
+    call assert_false(exists('#java_spotbugs_post#ShellCmdPost'))
+    call assert_false(exists('#java_spotbugs_test#ShellCmdPost'))
+
+    " Re-link a Funcref on the fly.
+    func! g:SpotBugsPreTestCommand(arguments) abort
+      let s:spotbugs_results.preTestActionOtherDone = 1
+      let s:spotbugs_results.preTestCommandArguments = a:arguments
+      " Define a once-only ":autocmd" for "#java_spotbugs_test#ShellCmdPost".
+      doautocmd java_spotbugs_post User
+      " XXX: Do NOT use ":cc" to notify the spotbugs compiler about success or
+      " failure, and assume the transfer of control to a ShellCmdPost command.
+    endfunc
+
+    doautocmd java_spotbugs User
+    " No match: "test_file !~# 'Xspotbugs/src'".
+    call assert_false(s:spotbugs_results.preActionDone)
+    call assert_true(empty(s:spotbugs_results.preCommandArguments))
+    " A match: "test_file =~# 'tests'".
+    call assert_true(s:spotbugs_results.preTestActionOtherDone)
+    call assert_equal('test-compile', 
s:spotbugs_results.preTestCommandArguments)
+    " For a pre-match, no post-action (without ":cc") UNLESS a ShellCmdPost
+    " event is consumed whose command will invoke "PostCompilerActionExecutor"
+    " and the latter will accept a post-compiler action argument.
+    call assert_false(s:spotbugs_results.postActionDone)
+    call assert_true(exists('#java_spotbugs_test#ShellCmdPost'))
+    doautocmd ShellCmdPost
+    call assert_false(exists('#java_spotbugs_test#ShellCmdPost'))
+    call assert_true(s:spotbugs_results.postActionDone)
+    call assert_equal('%:S', s:spotbugs_results.postCommandArguments)
+
+    " With a match, confirm that ":compiler spotbugs" has run.
+    if has('win32')
+      call assert_match('^spotbugs\.bat\s', &l:makeprg)
+    else
+      call assert_match('^spotbugs\s', &l:makeprg)
+    endif
+
     bwipeout
     setlocal makeprg=
   endif
diff --git a/src/version.c b/src/version.c
index 8b9036538..0815fc909 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    967,
 /**/
     966,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1tRCks-007URx-SC%40256bit.org.

Raspunde prin e-mail lui