Konfekt | 65311c6 | 2024-11-28 21:06:09 +0100 | [diff] [blame] | 1 | " Default pre- and post-compiler actions for SpotBugs |
| 2 | " Maintainers: @konfekt and @zzzyxwvut |
| 3 | " Last Change: 2024 Nov 27 |
| 4 | |
| 5 | let s:save_cpo = &cpo |
| 6 | set cpo&vim |
| 7 | |
| 8 | if v:version > 900 |
| 9 | |
| 10 | function! spotbugs#DeleteClassFiles() abort |
| 11 | if !exists('b:spotbugs_class_files') |
| 12 | return |
| 13 | endif |
| 14 | |
| 15 | for pathname in b:spotbugs_class_files |
| 16 | let classname = pathname =~# "^'.\\+\\.class'$" |
| 17 | \ ? eval(pathname) |
| 18 | \ : pathname |
| 19 | |
| 20 | if classname =~# '\.class$' && filereadable(classname) |
| 21 | " Since v9.0.0795. |
| 22 | let octad = readblob(classname, 0, 8) |
| 23 | |
| 24 | " Test the magic number and the major version number (45 for v1.0). |
| 25 | " Since v9.0.2027. |
| 26 | if len(octad) == 8 && octad[0 : 3] == 0zcafe.babe && |
| 27 | \ or((octad[6] << 8), octad[7]) >= 45 |
| 28 | echomsg printf('Deleting %s: %d', classname, delete(classname)) |
| 29 | endif |
| 30 | endif |
| 31 | endfor |
| 32 | |
| 33 | let b:spotbugs_class_files = [] |
| 34 | endfunction |
| 35 | |
| 36 | else |
| 37 | |
| 38 | function! s:DeleteClassFilesWithNewLineCodes(classname) abort |
| 39 | " The distribution of "0a"s in class file versions 2560 and 2570: |
| 40 | " |
| 41 | " 0zca.fe.ba.be.00.00.0a.00 0zca.fe.ba.be.00.00.0a.0a |
| 42 | " 0zca.fe.ba.be.00.0a.0a.00 0zca.fe.ba.be.00.0a.0a.0a |
| 43 | " 0zca.fe.ba.be.0a.00.0a.00 0zca.fe.ba.be.0a.00.0a.0a |
| 44 | " 0zca.fe.ba.be.0a.0a.0a.00 0zca.fe.ba.be.0a.0a.0a.0a |
| 45 | let numbers = [0, 0, 0, 0, 0, 0, 0, 0] |
| 46 | let offset = 0 |
| 47 | let lines = readfile(a:classname, 'b', 4) |
| 48 | |
| 49 | " Track NL byte counts to handle files of less than 8 bytes. |
| 50 | let nl_cnt = len(lines) |
| 51 | " Track non-NL byte counts for "0zca.fe.ba.be.0a.0a.0a.0a". |
| 52 | let non_nl_cnt = 0 |
| 53 | |
| 54 | for line in lines |
| 55 | for idx in range(strlen(line)) |
| 56 | " Remap NLs to Nuls. |
| 57 | let numbers[offset] = (line[idx] == "\n") ? 0 : char2nr(line[idx]) % 256 |
| 58 | let non_nl_cnt += 1 |
| 59 | let offset += 1 |
| 60 | |
| 61 | if offset > 7 |
| 62 | break |
| 63 | endif |
| 64 | endfor |
| 65 | |
| 66 | let nl_cnt -= 1 |
| 67 | |
| 68 | if offset > 7 || (nl_cnt < 1 && non_nl_cnt > 4) |
| 69 | break |
| 70 | endif |
| 71 | |
| 72 | " Reclaim NLs. |
| 73 | let numbers[offset] = 10 |
| 74 | let offset += 1 |
| 75 | |
| 76 | if offset > 7 |
| 77 | break |
| 78 | endif |
| 79 | endfor |
| 80 | |
| 81 | " Test the magic number and the major version number (45 for v1.0). |
| 82 | if offset > 7 && numbers[0] == 0xca && numbers[1] == 0xfe && |
| 83 | \ numbers[2] == 0xba && numbers[3] == 0xbe && |
| 84 | \ (numbers[6] * 256 + numbers[7]) >= 45 |
| 85 | echomsg printf('Deleting %s: %d', a:classname, delete(a:classname)) |
| 86 | endif |
| 87 | endfunction |
| 88 | |
| 89 | function! spotbugs#DeleteClassFiles() abort |
| 90 | if !exists('b:spotbugs_class_files') |
| 91 | return |
| 92 | endif |
| 93 | |
| 94 | let encoding = &encoding |
| 95 | |
| 96 | try |
| 97 | set encoding=latin1 |
| 98 | |
| 99 | for pathname in b:spotbugs_class_files |
| 100 | let classname = pathname =~# "^'.\\+\\.class'$" |
| 101 | \ ? eval(pathname) |
| 102 | \ : pathname |
| 103 | |
| 104 | if classname =~# '\.class$' && filereadable(classname) |
| 105 | let line = get(readfile(classname, 'b', 1), 0, '') |
| 106 | let length = strlen(line) |
| 107 | |
| 108 | " Test the magic number and the major version number (45 for v1.0). |
| 109 | if length > 3 && line[0 : 3] == "\xca\xfe\xba\xbe" |
| 110 | if length > 7 && ((line[6] == "\n" ? 0 : char2nr(line[6]) % 256) * 256 + |
| 111 | \ (line[7] == "\n" ? 0 : char2nr(line[7]) % 256)) >= 45 |
| 112 | echomsg printf('Deleting %s: %d', classname, delete(classname)) |
| 113 | else |
| 114 | call s:DeleteClassFilesWithNewLineCodes(classname) |
| 115 | endif |
| 116 | endif |
| 117 | endif |
| 118 | endfor |
| 119 | finally |
| 120 | let &encoding = encoding |
| 121 | endtry |
| 122 | |
| 123 | let b:spotbugs_class_files = [] |
| 124 | endfunction |
| 125 | |
| 126 | endif |
| 127 | |
| 128 | function! spotbugs#DefaultPostCompilerAction() abort |
| 129 | " Since v7.4.191. |
| 130 | make %:S |
| 131 | endfunction |
| 132 | |
| 133 | " Look for "spotbugs#compiler" in "ftplugin/java.vim". |
| 134 | let s:compiler = exists('spotbugs#compiler') ? spotbugs#compiler : '' |
| 135 | let s:readable = filereadable($VIMRUNTIME . '/compiler/' . s:compiler . '.vim') |
| 136 | |
| 137 | if s:readable && s:compiler ==# 'maven' && executable('mvn') |
| 138 | |
| 139 | function! spotbugs#DefaultPreCompilerAction() abort |
| 140 | call spotbugs#DeleteClassFiles() |
| 141 | compiler maven |
| 142 | make compile |
| 143 | endfunction |
| 144 | |
| 145 | function! spotbugs#DefaultPreCompilerTestAction() abort |
| 146 | call spotbugs#DeleteClassFiles() |
| 147 | compiler maven |
| 148 | make test-compile |
| 149 | endfunction |
| 150 | |
| 151 | function! spotbugs#DefaultProperties() abort |
| 152 | return { |
| 153 | \ 'PreCompilerAction': |
| 154 | \ function('spotbugs#DefaultPreCompilerAction'), |
| 155 | \ 'PreCompilerTestAction': |
| 156 | \ function('spotbugs#DefaultPreCompilerTestAction'), |
| 157 | \ 'PostCompilerAction': |
| 158 | \ function('spotbugs#DefaultPostCompilerAction'), |
| 159 | \ 'sourceDirPath': 'src/main/java', |
| 160 | \ 'classDirPath': 'target/classes', |
| 161 | \ 'testSourceDirPath': 'src/test/java', |
| 162 | \ 'testClassDirPath': 'target/test-classes', |
| 163 | \ } |
| 164 | endfunction |
| 165 | |
| 166 | unlet s:readable s:compiler |
| 167 | elseif s:readable && s:compiler ==# 'ant' && executable('ant') |
| 168 | |
| 169 | function! spotbugs#DefaultPreCompilerAction() abort |
| 170 | call spotbugs#DeleteClassFiles() |
| 171 | compiler ant |
| 172 | make compile |
| 173 | endfunction |
| 174 | |
| 175 | function! spotbugs#DefaultPreCompilerTestAction() abort |
| 176 | call spotbugs#DeleteClassFiles() |
| 177 | compiler ant |
| 178 | make compile-test |
| 179 | endfunction |
| 180 | |
| 181 | function! spotbugs#DefaultProperties() abort |
| 182 | return { |
| 183 | \ 'PreCompilerAction': |
| 184 | \ function('spotbugs#DefaultPreCompilerAction'), |
| 185 | \ 'PreCompilerTestAction': |
| 186 | \ function('spotbugs#DefaultPreCompilerTestAction'), |
| 187 | \ 'PostCompilerAction': |
| 188 | \ function('spotbugs#DefaultPostCompilerAction'), |
| 189 | \ 'sourceDirPath': 'src', |
| 190 | \ 'classDirPath': 'build/classes', |
| 191 | \ 'testSourceDirPath': 'test', |
| 192 | \ 'testClassDirPath': 'build/test/classes', |
| 193 | \ } |
| 194 | endfunction |
| 195 | |
| 196 | unlet s:readable s:compiler |
| 197 | elseif s:readable && s:compiler ==# 'javac' && executable('javac') |
| 198 | |
| 199 | function! spotbugs#DefaultPreCompilerAction() abort |
| 200 | call spotbugs#DeleteClassFiles() |
| 201 | compiler javac |
| 202 | |
| 203 | if get(b:, 'javac_makeprg_params', get(g:, 'javac_makeprg_params', '')) =~ '\s@\S' |
| 204 | " Read options and filenames from @options [@sources ...]. |
| 205 | make |
| 206 | else |
| 207 | " Let Javac figure out what files to compile. |
| 208 | execute 'make ' . join(map(filter(copy(v:argv), |
| 209 | \ "v:val =~# '\\.java\\=$'"), |
| 210 | \ 'shellescape(v:val)'), ' ') |
| 211 | endif |
| 212 | endfunction |
| 213 | |
| 214 | function! spotbugs#DefaultPreCompilerTestAction() abort |
| 215 | call spotbugs#DefaultPreCompilerAction() |
| 216 | endfunction |
| 217 | |
| 218 | function! spotbugs#DefaultProperties() abort |
| 219 | return { |
| 220 | \ 'PreCompilerAction': |
| 221 | \ function('spotbugs#DefaultPreCompilerAction'), |
| 222 | \ 'PreCompilerTestAction': |
| 223 | \ function('spotbugs#DefaultPreCompilerTestAction'), |
| 224 | \ 'PostCompilerAction': |
| 225 | \ function('spotbugs#DefaultPostCompilerAction'), |
| 226 | \ } |
| 227 | endfunction |
| 228 | |
| 229 | unlet s:readable s:compiler |
| 230 | else |
| 231 | |
| 232 | function! spotbugs#DefaultPreCompilerAction() abort |
| 233 | echomsg printf('Not supported: "%s"', s:compiler) |
| 234 | endfunction |
| 235 | |
| 236 | function! spotbugs#DefaultPreCompilerTestAction() abort |
| 237 | call spotbugs#DefaultPreCompilerAction() |
| 238 | endfunction |
| 239 | |
| 240 | function! spotbugs#DefaultProperties() abort |
| 241 | return {} |
| 242 | endfunction |
| 243 | |
| 244 | unlet s:readable |
| 245 | endif |
| 246 | |
| 247 | let &cpo = s:save_cpo |
| 248 | unlet s:save_cpo |
| 249 | |
| 250 | " vim: set foldmethod=syntax shiftwidth=2 expandtab: |