Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
spotbugs.vim255 linesDownload Raw Back to compiler
1" Vim compiler file2" Compiler:     Spotbugs (Java static checker; needs javac compiled classes)3" Maintainers:  @konfekt and @zzzyxwvut4" Last Change:  2024 Dec 205 6if exists('g:current_compiler') || bufname() !~# '\.java\=$' || wordcount().chars < 97  finish8endif9 10let s:cpo_save = &cpo11set cpo&vim12 13" Unfortunately Spotbugs does not output absolute paths, so you need to14" pass the directory of the files being checked as `-sourcepath` parameter.15" The regex, auxpath and glob try to include all dependent classes of the16" current buffer. See https://github.com/spotbugs/spotbugs/issues/85617 18" FIXME: When "search()" is used with the "e" flag, it makes no _further_19" progress after claiming an EOL match (i.e. "\_" or "\n", but not "$").20" XXX: Omit anonymous class declarations21let s:keywords = '\C\<\%(\.\@1<!class\|@\=interface\|enum\|record\|package\)\%(\s\|$\)'22let s:type_names = '\C\<\%(\.\@1<!class\|@\=interface\|enum\|record\)\s*\(\K\k*\)\>'23" Capture ";" for counting a class file directory (see s:package_dir_heads below)24let s:package_names = '\C\<package\s*\(\K\%(\k*\.\=\)\+;\)'25let s:package = ''26 27if has('syntax') && exists('g:syntax_on') &&28    \ exists('b:current_syntax') && b:current_syntax == 'java' &&29    \ hlexists('javaClassDecl') && hlexists('javaExternal')30 31  function! s:GetDeclaredTypeNames() abort32    if bufname() =~# '\<\%(module\|package\)-info\.java\=$'33      return [expand('%:t:r')]34    endif35    defer execute('silent! normal! g``')36    call cursor(1, 1)37    let type_names = []38    let lnum = search(s:keywords, 'eW')39    while lnum > 040      let name_attr = synIDattr(synID(lnum, (col('.') - 1), 0), 'name')41      if name_attr ==# 'javaClassDecl'42        let tokens = matchlist(getline(lnum)..getline(lnum + 1), s:type_names)43        if !empty(tokens) | call add(type_names, tokens[1]) | endif44      elseif name_attr ==# 'javaExternal'45        let tokens = matchlist(getline(lnum)..getline(lnum + 1), s:package_names)46        if !empty(tokens) | let s:package = tokens[1] | endif47      endif48      let lnum = search(s:keywords, 'eW')49    endwhile50    return type_names51  endfunction52 53else54  function! s:GetDeclaredTypeNames() abort55    if bufname() =~# '\<\%(module\|package\)-info\.java\=$'56      return [expand('%:t:r')]57    endif58    " Undo the unsetting of &hls, see below59    if &hls60      defer execute('set hls')61    endif62    " Possibly restore the current values for registers '"' and "y", see below63    defer call('setreg', ['"', getreg('"'), getregtype('"')])64    defer call('setreg', ['y', getreg('y'), getregtype('y')])65    defer execute('silent bwipeout')66    " Copy buffer contents for modification67    silent %y y68    new69    " Apply ":help scratch-buffer" effects and match "$" in Java (generated)70    " type names (see s:type_names)71    setlocal iskeyword+=$ buftype=nofile bufhidden=hide noswapfile nohls72    0put y73    " Discard text blocks and strings74    silent keeppatterns %s/\\\@<!"""\_.\{-}\\\@<!"""\|\\"//ge75    silent keeppatterns %s/".*"//ge76    " Discard comments77    silent keeppatterns %s/\/\/.\+$//ge78    silent keeppatterns %s/\/\*\_.\{-}\*\///ge79    call cursor(1, 1)80    let type_names = []81    let lnum = search(s:keywords, 'eW')82    while lnum > 083      let line = getline(lnum)84      if line =~# '\<package\>'85        let tokens = matchlist(line..getline(lnum + 1), s:package_names)86        if !empty(tokens) | let s:package = tokens[1] | endif87      else88        let tokens = matchlist(line..getline(lnum + 1), s:type_names)89        if !empty(tokens) | call add(type_names, tokens[1]) | endif90      endif91      let lnum = search(s:keywords, 'eW')92    endwhile93    return type_names94  endfunction95endif96 97if has('win32')98 99  function! s:GlobClassFiles(src_type_name) abort100    return glob(a:src_type_name..'$*.class', 1, 1)101  endfunction102 103else104  function! s:GlobClassFiles(src_type_name) abort105    return glob(a:src_type_name..'\$*.class', 1, 1)106  endfunction107endif108 109if exists('b:spotbugs_properties')110  " Let "ftplugin/java.vim" merge global entries, if any, in buffer-local111  " entries112 113  function! s:GetProperty(name, default) abort114    return get(b:spotbugs_properties, a:name, a:default)115  endfunction116 117elseif exists('g:spotbugs_properties')118 119  function! s:GetProperty(name, default) abort120    return get(g:spotbugs_properties, a:name, a:default)121  endfunction122 123else124  function! s:GetProperty(dummy, default) abort125    return a:default126  endfunction127endif128 129if (exists('g:spotbugs_properties') || exists('b:spotbugs_properties')) &&130    \ ((!empty(s:GetProperty('sourceDirPath', [])) &&131        \ !empty(s:GetProperty('classDirPath', []))) ||132    \ (!empty(s:GetProperty('testSourceDirPath', [])) &&133        \ !empty(s:GetProperty('testClassDirPath', []))))134 135  function! s:CommonIdxsAndDirs() abort136    let src_dir_path = s:GetProperty('sourceDirPath', [])137    let bin_dir_path = s:GetProperty('classDirPath', [])138    let test_src_dir_path = s:GetProperty('testSourceDirPath', [])139    let test_bin_dir_path = s:GetProperty('testClassDirPath', [])140    let dir_cnt = min([len(src_dir_path), len(bin_dir_path)])141    let test_dir_cnt = min([len(test_src_dir_path), len(test_bin_dir_path)])142    " Do not break up path pairs with filtering!143    return [[range(dir_cnt),144            \ src_dir_path[0 : dir_cnt - 1],145            \ bin_dir_path[0 : dir_cnt - 1]],146        \ [range(test_dir_cnt),147            \ test_src_dir_path[0 : test_dir_cnt - 1],148            \ test_bin_dir_path[0 : test_dir_cnt - 1]]]149  endfunction150 151  let s:common_idxs_and_dirs = s:CommonIdxsAndDirs()152  delfunction s:CommonIdxsAndDirs153 154  function! s:FindClassFiles(src_type_name) abort155    let class_files = []156    " Match pairwise the components of source and class pathnames157    for [idxs, src_dirs, bin_dirs] in s:common_idxs_and_dirs158      " Do not use "fnamemodify(a:src_type_name, ':p:s?src?bin?')" because159      " only the rightmost "src" is looked for160      for idx in idxs161        let tail_idx = strridx(a:src_type_name, src_dirs[idx])162        " No such directory or no such inner type (i.e. without "$")163        if tail_idx < 0 | continue | endif164        " Substitute "bin_dirs[idx]" for the rightmost "src_dirs[idx]"165        let candidate_type_name = strpart(a:src_type_name, 0, tail_idx)..166            \ bin_dirs[idx]..167            \ strpart(a:src_type_name, (tail_idx + strlen(src_dirs[idx])))168        for candidate in insert(s:GlobClassFiles(candidate_type_name),169              \ candidate_type_name..'.class')170          if filereadable(candidate) | call add(class_files, shellescape(candidate)) | endif171        endfor172        if !empty(class_files) | break | endif173      endfor174      if !empty(class_files) | break | endif175    endfor176    return class_files177  endfunction178 179else180  function! s:FindClassFiles(src_type_name) abort181    let class_files = []182    for candidate in insert(s:GlobClassFiles(a:src_type_name),183          \ a:src_type_name..'.class')184      if filereadable(candidate) | call add(class_files, shellescape(candidate)) | endif185    endfor186    return class_files187  endfunction188endif189 190if exists('g:spotbugs_alternative_path') &&191    \ !empty(get(g:spotbugs_alternative_path, 'fromPath', '')) &&192    \ !empty(get(g:spotbugs_alternative_path, 'toPath', ''))193 194  " See https://github.com/spotbugs/spotbugs/issues/909195  function! s:ResolveAbsolutePathname() abort196    let pathname = expand('%:p')197    let head_idx = stridx(pathname, g:spotbugs_alternative_path.toPath)198    " No such file: a mismatched path request for a project199    if head_idx < 0 | return pathname | endif200    " Settle for failure with file readability tests _in s:FindClassFiles()_201    return strpart(pathname, 0, head_idx)..202        \ g:spotbugs_alternative_path.fromPath..203        \ strpart(pathname, (head_idx + strlen(g:spotbugs_alternative_path.toPath)))204  endfunction205 206else207  function! s:ResolveAbsolutePathname() abort208    return expand('%:p')209  endfunction210endif211 212function! s:CollectClassFiles() abort213  " Possibly obtain a symlinked path for an unsupported directory name214  let pathname = s:ResolveAbsolutePathname()215  " Get a platform-independent pathname prefix, cf. "expand('%:p:h')..'/'"216  let tail_idx = strridx(pathname, expand('%:t'))217  let src_pathname = strpart(pathname, 0, tail_idx)218  let all_class_files = []219  " Get all type names in the current buffer and let the filename globbing220  " discover inner type names from arbitrary type names221  for type_name in s:GetDeclaredTypeNames()222    call extend(all_class_files, s:FindClassFiles(src_pathname..type_name))223  endfor224  return all_class_files225endfunction226 227" Expose class files for removal etc.228let b:spotbugs_class_files = s:CollectClassFiles()229let s:package_dir_heads = repeat(':h', (1 + strlen(substitute(s:package, '[^.;]', '', 'g'))))230let s:package_root_dir = fnamemodify(s:ResolveAbsolutePathname(), s:package_dir_heads..':S')231let g:current_compiler = 'spotbugs'232" CompilerSet makeprg=spotbugs233let &l:makeprg = 'spotbugs'..(has('win32') ? '.bat' : '')..' '..234    \ get(b:, 'spotbugs_makeprg_params', get(g:, 'spotbugs_makeprg_params', '-workHard -experimental'))..235    \ ' -textui -emacs -auxclasspath '..s:package_root_dir..' -sourcepath '..s:package_root_dir..' '..236    \ join(b:spotbugs_class_files, ' ')237" Emacs expects doubled line numbers238setlocal errorformat=%f:%l:%*[0-9]\ %m,%f:-%*[0-9]:-%*[0-9]\ %m239 240" " This compiler is meant to be used for a single buffer only241" exe 'CompilerSet makeprg='..escape(&l:makeprg, ' \|"')242" exe 'CompilerSet errorformat='..escape(&l:errorformat, ' \|"')243 244delfunction s:CollectClassFiles245delfunction s:ResolveAbsolutePathname246delfunction s:FindClassFiles247delfunction s:GetProperty248delfunction s:GlobClassFiles249delfunction s:GetDeclaredTypeNames250let &cpo = s:cpo_save251unlet! s:package_root_dir s:package_dir_heads s:common_idxs_and_dirs s:package252unlet! s:package_names s:type_names s:keywords s:cpo_save253 254" vim: set foldmethod=syntax shiftwidth=2 expandtab:255 
codekingpro/portable-devtools · Team Ai