blob: 9161395794ea248ae16e551a7ef388d91d2de538 [file] [log] [blame]
Konfekt65311c62024-11-28 21:06:09 +01001" Default pre- and post-compiler actions for SpotBugs
2" Maintainers: @konfekt and @zzzyxwvut
3" Last Change: 2024 Nov 27
4
5let s:save_cpo = &cpo
6set cpo&vim
7
8if 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
36else
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
126endif
127
128function! spotbugs#DefaultPostCompilerAction() abort
129 " Since v7.4.191.
130 make %:S
131endfunction
132
133" Look for "spotbugs#compiler" in "ftplugin/java.vim".
134let s:compiler = exists('spotbugs#compiler') ? spotbugs#compiler : ''
135let s:readable = filereadable($VIMRUNTIME . '/compiler/' . s:compiler . '.vim')
136
137if 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
167elseif 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
197elseif 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
230else
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
245endif
246
247let &cpo = s:save_cpo
248unlet s:save_cpo
249
250" vim: set foldmethod=syntax shiftwidth=2 expandtab: