/usr/share/doc/libcobertura-java/api/src-html/net/sourceforge/cobertura/instrument/SecondPassMethodInstrumenter.html is in libcobertura-java-doc 1.9.4.1+dfsg-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<title>Source code</title>
<link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style">
</head>
<body>
<div class="sourceContainer">
<pre><span class="sourceLineNo">001</span>/*<a name="line.1"></a>
<span class="sourceLineNo">002</span> * Cobertura - http://cobertura.sourceforge.net/<a name="line.2"></a>
<span class="sourceLineNo">003</span> *<a name="line.3"></a>
<span class="sourceLineNo">004</span> * Copyright (C) 2005 Mark Doliner<a name="line.4"></a>
<span class="sourceLineNo">005</span> * Copyright (C) 2006 Jiri Mares<a name="line.5"></a>
<span class="sourceLineNo">006</span> * Copyright (C) 2010 Piotr Tabor<a name="line.6"></a>
<span class="sourceLineNo">007</span> *<a name="line.7"></a>
<span class="sourceLineNo">008</span> * Cobertura is free software; you can redistribute it and/or modify<a name="line.8"></a>
<span class="sourceLineNo">009</span> * it under the terms of the GNU General Public License as published<a name="line.9"></a>
<span class="sourceLineNo">010</span> * by the Free Software Foundation; either version 2 of the License,<a name="line.10"></a>
<span class="sourceLineNo">011</span> * or (at your option) any later version.<a name="line.11"></a>
<span class="sourceLineNo">012</span> *<a name="line.12"></a>
<span class="sourceLineNo">013</span> * Cobertura is distributed in the hope that it will be useful, but<a name="line.13"></a>
<span class="sourceLineNo">014</span> * WITHOUT ANY WARRANTY; without even the implied warranty of<a name="line.14"></a>
<span class="sourceLineNo">015</span> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU<a name="line.15"></a>
<span class="sourceLineNo">016</span> * General Public License for more details.<a name="line.16"></a>
<span class="sourceLineNo">017</span> *<a name="line.17"></a>
<span class="sourceLineNo">018</span> * You should have received a copy of the GNU General Public License<a name="line.18"></a>
<span class="sourceLineNo">019</span> * along with Cobertura; if not, write to the Free Software<a name="line.19"></a>
<span class="sourceLineNo">020</span> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307<a name="line.20"></a>
<span class="sourceLineNo">021</span> * USA<a name="line.21"></a>
<span class="sourceLineNo">022</span> */<a name="line.22"></a>
<span class="sourceLineNo">023</span><a name="line.23"></a>
<span class="sourceLineNo">024</span>package net.sourceforge.cobertura.instrument;<a name="line.24"></a>
<span class="sourceLineNo">025</span><a name="line.25"></a>
<span class="sourceLineNo">026</span>import net.sourceforge.cobertura.util.RegexUtil;<a name="line.26"></a>
<span class="sourceLineNo">027</span><a name="line.27"></a>
<span class="sourceLineNo">028</span>import org.objectweb.asm.Label;<a name="line.28"></a>
<span class="sourceLineNo">029</span>import org.objectweb.asm.Opcodes;<a name="line.29"></a>
<span class="sourceLineNo">030</span><a name="line.30"></a>
<span class="sourceLineNo">031</span>/*<a name="line.31"></a>
<span class="sourceLineNo">032</span> * TODO: If class is abstract then do not count the "public abstract class bleh" line as a SLOC.<a name="line.32"></a>
<span class="sourceLineNo">033</span> */<a name="line.33"></a>
<span class="sourceLineNo">034</span>public class SecondPassMethodInstrumenter extends NewLocalVariableMethodAdapter implements Opcodes<a name="line.34"></a>
<span class="sourceLineNo">035</span>{<a name="line.35"></a>
<span class="sourceLineNo">036</span> private String TOUCH_COLLECTOR_CLASS="net/sourceforge/cobertura/coveragedata/TouchCollector";<a name="line.36"></a>
<span class="sourceLineNo">037</span> <a name="line.37"></a>
<span class="sourceLineNo">038</span> private int currentLine;<a name="line.38"></a>
<span class="sourceLineNo">039</span> <a name="line.39"></a>
<span class="sourceLineNo">040</span> private int currentJump;<a name="line.40"></a>
<span class="sourceLineNo">041</span> <a name="line.41"></a>
<span class="sourceLineNo">042</span> private boolean methodStarted;<a name="line.42"></a>
<span class="sourceLineNo">043</span> <a name="line.43"></a>
<span class="sourceLineNo">044</span> private int myVariableIndex;<a name="line.44"></a>
<span class="sourceLineNo">045</span><a name="line.45"></a>
<span class="sourceLineNo">046</span> private Label startLabel;<a name="line.46"></a>
<span class="sourceLineNo">047</span> <a name="line.47"></a>
<span class="sourceLineNo">048</span> private Label endLabel;<a name="line.48"></a>
<span class="sourceLineNo">049</span> <a name="line.49"></a>
<span class="sourceLineNo">050</span> private JumpHolder lastJump;<a name="line.50"></a>
<span class="sourceLineNo">051</span> <a name="line.51"></a>
<span class="sourceLineNo">052</span> private FirstPassMethodInstrumenter firstPass;<a name="line.52"></a>
<span class="sourceLineNo">053</span> <a name="line.53"></a>
<span class="sourceLineNo">054</span> private static final int BOOLEAN_TRUE = ICONST_0;<a name="line.54"></a>
<span class="sourceLineNo">055</span> private static final int BOOLEAN_FALSE = ICONST_1;<a name="line.55"></a>
<span class="sourceLineNo">056</span><a name="line.56"></a>
<span class="sourceLineNo">057</span> public SecondPassMethodInstrumenter(FirstPassMethodInstrumenter firstPass)<a name="line.57"></a>
<span class="sourceLineNo">058</span> {<a name="line.58"></a>
<span class="sourceLineNo">059</span> super(firstPass.getWriterMethodVisitor(), firstPass.getMyAccess(), firstPass.getMyDescriptor(), 2);<a name="line.59"></a>
<span class="sourceLineNo">060</span> this.firstPass = firstPass;<a name="line.60"></a>
<span class="sourceLineNo">061</span> this.currentLine = 0;<a name="line.61"></a>
<span class="sourceLineNo">062</span> }<a name="line.62"></a>
<span class="sourceLineNo">063</span><a name="line.63"></a>
<span class="sourceLineNo">064</span> public void visitJumpInsn(int opcode, Label label)<a name="line.64"></a>
<span class="sourceLineNo">065</span> {<a name="line.65"></a>
<span class="sourceLineNo">066</span> //to touch the previous branch (when there is such)<a name="line.66"></a>
<span class="sourceLineNo">067</span> touchBranchFalse();<a name="line.67"></a>
<span class="sourceLineNo">068</span> <a name="line.68"></a>
<span class="sourceLineNo">069</span> // Ignore any jump instructions in the "class init" method.<a name="line.69"></a>
<span class="sourceLineNo">070</span> // When initializing static variables, the JVM first checks<a name="line.70"></a>
<span class="sourceLineNo">071</span> // that the variable is null before attempting to set it.<a name="line.71"></a>
<span class="sourceLineNo">072</span> // This check contains an IFNONNULL jump instruction which<a name="line.72"></a>
<span class="sourceLineNo">073</span> // would confuse people if it showed up in the reports.<a name="line.73"></a>
<span class="sourceLineNo">074</span> if ((opcode != GOTO) && (opcode != JSR) && (currentLine != 0)<a name="line.74"></a>
<span class="sourceLineNo">075</span> && (!this.firstPass.getMyName().equals("<clinit>")))<a name="line.75"></a>
<span class="sourceLineNo">076</span> {<a name="line.76"></a>
<span class="sourceLineNo">077</span> lastJump = new JumpHolder(currentLine, currentJump++); <a name="line.77"></a>
<span class="sourceLineNo">078</span> mv.visitIntInsn(SIPUSH, currentLine);<a name="line.78"></a>
<span class="sourceLineNo">079</span> mv.visitVarInsn(ISTORE, myVariableIndex);<a name="line.79"></a>
<span class="sourceLineNo">080</span> mv.visitIntInsn(SIPUSH, lastJump.getJumpNumber());<a name="line.80"></a>
<span class="sourceLineNo">081</span> mv.visitVarInsn(ISTORE, myVariableIndex + 1);<a name="line.81"></a>
<span class="sourceLineNo">082</span> }<a name="line.82"></a>
<span class="sourceLineNo">083</span> <a name="line.83"></a>
<span class="sourceLineNo">084</span> super.visitJumpInsn(opcode, label);<a name="line.84"></a>
<span class="sourceLineNo">085</span> }<a name="line.85"></a>
<span class="sourceLineNo">086</span><a name="line.86"></a>
<span class="sourceLineNo">087</span> public void visitLineNumber(int line, Label start)<a name="line.87"></a>
<span class="sourceLineNo">088</span> {<a name="line.88"></a>
<span class="sourceLineNo">089</span> // Record initial information about this line of code<a name="line.89"></a>
<span class="sourceLineNo">090</span> currentLine = line;<a name="line.90"></a>
<span class="sourceLineNo">091</span> currentJump = 0;<a name="line.91"></a>
<span class="sourceLineNo">092</span><a name="line.92"></a>
<span class="sourceLineNo">093</span> instrumentOwnerClass();<a name="line.93"></a>
<span class="sourceLineNo">094</span><a name="line.94"></a>
<span class="sourceLineNo">095</span> // Mark the current line number as covered:<a name="line.95"></a>
<span class="sourceLineNo">096</span> // classData.touch(line)<a name="line.96"></a>
<span class="sourceLineNo">097</span> mv.visitIntInsn(SIPUSH, line);<a name="line.97"></a>
<span class="sourceLineNo">098</span> mv.visitMethodInsn(INVOKESTATIC,<a name="line.98"></a>
<span class="sourceLineNo">099</span> TOUCH_COLLECTOR_CLASS, "touch",<a name="line.99"></a>
<span class="sourceLineNo">100</span> "(Ljava/lang/String;I)V");<a name="line.100"></a>
<span class="sourceLineNo">101</span><a name="line.101"></a>
<span class="sourceLineNo">102</span> super.visitLineNumber(line, start);<a name="line.102"></a>
<span class="sourceLineNo">103</span> }<a name="line.103"></a>
<span class="sourceLineNo">104</span><a name="line.104"></a>
<span class="sourceLineNo">105</span> public void visitMethodInsn(int opcode, String owner, String name,<a name="line.105"></a>
<span class="sourceLineNo">106</span> String desc)<a name="line.106"></a>
<span class="sourceLineNo">107</span> {<a name="line.107"></a>
<span class="sourceLineNo">108</span> //to touch the previous branch (when there is such)<a name="line.108"></a>
<span class="sourceLineNo">109</span> touchBranchFalse();<a name="line.109"></a>
<span class="sourceLineNo">110</span> <a name="line.110"></a>
<span class="sourceLineNo">111</span> super.visitMethodInsn(opcode, owner, name, desc);<a name="line.111"></a>
<span class="sourceLineNo">112</span><a name="line.112"></a>
<span class="sourceLineNo">113</span> // If any of the ignore patterns match this line<a name="line.113"></a>
<span class="sourceLineNo">114</span> // then remove it from our data<a name="line.114"></a>
<span class="sourceLineNo">115</span> if (RegexUtil.matches(firstPass.getIgnoreRegexs(), owner)) <a name="line.115"></a>
<span class="sourceLineNo">116</span> {<a name="line.116"></a>
<span class="sourceLineNo">117</span> firstPass.removeLine(currentLine);<a name="line.117"></a>
<span class="sourceLineNo">118</span> }<a name="line.118"></a>
<span class="sourceLineNo">119</span> }<a name="line.119"></a>
<span class="sourceLineNo">120</span><a name="line.120"></a>
<span class="sourceLineNo">121</span> public void visitFieldInsn(int opcode, String owner, String name, String desc)<a name="line.121"></a>
<span class="sourceLineNo">122</span> {<a name="line.122"></a>
<span class="sourceLineNo">123</span> //to touch the previous branch (when there is such)<a name="line.123"></a>
<span class="sourceLineNo">124</span> touchBranchFalse();<a name="line.124"></a>
<span class="sourceLineNo">125</span> <a name="line.125"></a>
<span class="sourceLineNo">126</span> super.visitFieldInsn(opcode, owner, name, desc);<a name="line.126"></a>
<span class="sourceLineNo">127</span> }<a name="line.127"></a>
<span class="sourceLineNo">128</span><a name="line.128"></a>
<span class="sourceLineNo">129</span> public void visitIincInsn(int var, int increment)<a name="line.129"></a>
<span class="sourceLineNo">130</span> {<a name="line.130"></a>
<span class="sourceLineNo">131</span> //to touch the previous branch (when there is such)<a name="line.131"></a>
<span class="sourceLineNo">132</span> touchBranchFalse();<a name="line.132"></a>
<span class="sourceLineNo">133</span> <a name="line.133"></a>
<span class="sourceLineNo">134</span> super.visitIincInsn(var, increment);<a name="line.134"></a>
<span class="sourceLineNo">135</span> }<a name="line.135"></a>
<span class="sourceLineNo">136</span><a name="line.136"></a>
<span class="sourceLineNo">137</span> public void visitInsn(int opcode)<a name="line.137"></a>
<span class="sourceLineNo">138</span> {<a name="line.138"></a>
<span class="sourceLineNo">139</span> //to touch the previous branch (when there is such)<a name="line.139"></a>
<span class="sourceLineNo">140</span> touchBranchFalse();<a name="line.140"></a>
<span class="sourceLineNo">141</span> <a name="line.141"></a>
<span class="sourceLineNo">142</span> super.visitInsn(opcode);<a name="line.142"></a>
<span class="sourceLineNo">143</span> }<a name="line.143"></a>
<span class="sourceLineNo">144</span><a name="line.144"></a>
<span class="sourceLineNo">145</span> public void visitIntInsn(int opcode, int operand)<a name="line.145"></a>
<span class="sourceLineNo">146</span> {<a name="line.146"></a>
<span class="sourceLineNo">147</span> //to touch the previous branch (when there is such)<a name="line.147"></a>
<span class="sourceLineNo">148</span> touchBranchFalse();<a name="line.148"></a>
<span class="sourceLineNo">149</span> <a name="line.149"></a>
<span class="sourceLineNo">150</span> super.visitIntInsn(opcode, operand);<a name="line.150"></a>
<span class="sourceLineNo">151</span> }<a name="line.151"></a>
<span class="sourceLineNo">152</span><a name="line.152"></a>
<span class="sourceLineNo">153</span> public void visitLabel(Label label)<a name="line.153"></a>
<span class="sourceLineNo">154</span> {<a name="line.154"></a>
<span class="sourceLineNo">155</span> //When this is the first method's label ... create the 2 new local variables (lineNumber and branchNumber)<a name="line.155"></a>
<span class="sourceLineNo">156</span> if (methodStarted) <a name="line.156"></a>
<span class="sourceLineNo">157</span> {<a name="line.157"></a>
<span class="sourceLineNo">158</span> methodStarted = false;<a name="line.158"></a>
<span class="sourceLineNo">159</span> myVariableIndex = getFirstStackVariable();<a name="line.159"></a>
<span class="sourceLineNo">160</span> mv.visitInsn(ICONST_0);<a name="line.160"></a>
<span class="sourceLineNo">161</span> mv.visitVarInsn(ISTORE, myVariableIndex);<a name="line.161"></a>
<span class="sourceLineNo">162</span> mv.visitIntInsn(SIPUSH, -1); <a name="line.162"></a>
<span class="sourceLineNo">163</span> mv.visitVarInsn(ISTORE, myVariableIndex + 1);<a name="line.163"></a>
<span class="sourceLineNo">164</span> startLabel = label;<a name="line.164"></a>
<span class="sourceLineNo">165</span> }<a name="line.165"></a>
<span class="sourceLineNo">166</span> //to have the last label for visitLocalVariable<a name="line.166"></a>
<span class="sourceLineNo">167</span> endLabel = label;<a name="line.167"></a>
<span class="sourceLineNo">168</span> <a name="line.168"></a>
<span class="sourceLineNo">169</span> super.visitLabel(label);<a name="line.169"></a>
<span class="sourceLineNo">170</span> <a name="line.170"></a>
<span class="sourceLineNo">171</span> //instrument the branch coverage collection<a name="line.171"></a>
<span class="sourceLineNo">172</span> if (firstPass.getJumpTargetLabels().keySet().contains(label)) <a name="line.172"></a>
<span class="sourceLineNo">173</span> { //this label is the true branch label<a name="line.173"></a>
<span class="sourceLineNo">174</span> if (lastJump != null) <a name="line.174"></a>
<span class="sourceLineNo">175</span> { //this is also label after jump - we have to check the branch number whether this is the true or false branch<a name="line.175"></a>
<span class="sourceLineNo">176</span> Label newLabelX = instrumentIsLastJump();<a name="line.176"></a>
<span class="sourceLineNo">177</span> instrumentOwnerClass();<a name="line.177"></a>
<span class="sourceLineNo">178</span> instrumentPutLineAndBranchNumbers();<a name="line.178"></a>
<span class="sourceLineNo">179</span> mv.visitInsn(BOOLEAN_FALSE);<a name="line.179"></a>
<span class="sourceLineNo">180</span> instrumentInvokeTouchJump();<a name="line.180"></a>
<span class="sourceLineNo">181</span> Label newLabelY = new Label();<a name="line.181"></a>
<span class="sourceLineNo">182</span> mv.visitJumpInsn(GOTO, newLabelY);<a name="line.182"></a>
<span class="sourceLineNo">183</span> mv.visitLabel(newLabelX);<a name="line.183"></a>
<span class="sourceLineNo">184</span> mv.visitVarInsn(ILOAD, myVariableIndex + 1);<a name="line.184"></a>
<span class="sourceLineNo">185</span> mv.visitJumpInsn(IFLT, newLabelY);<a name="line.185"></a>
<span class="sourceLineNo">186</span> instrumentOwnerClass();<a name="line.186"></a>
<span class="sourceLineNo">187</span> instrumentPutLineAndBranchNumbers();<a name="line.187"></a>
<span class="sourceLineNo">188</span> mv.visitInsn(BOOLEAN_TRUE);<a name="line.188"></a>
<span class="sourceLineNo">189</span> instrumentInvokeTouchJump();<a name="line.189"></a>
<span class="sourceLineNo">190</span> mv.visitLabel(newLabelY);<a name="line.190"></a>
<span class="sourceLineNo">191</span> }<a name="line.191"></a>
<span class="sourceLineNo">192</span> else<a name="line.192"></a>
<span class="sourceLineNo">193</span> { //just hit te true branch<a name="line.193"></a>
<span class="sourceLineNo">194</span> //just check whether the jump has been invoked or the label has been touched other way <a name="line.194"></a>
<span class="sourceLineNo">195</span> mv.visitVarInsn(ILOAD, myVariableIndex + 1);<a name="line.195"></a>
<span class="sourceLineNo">196</span> Label newLabelX = new Label();<a name="line.196"></a>
<span class="sourceLineNo">197</span> mv.visitJumpInsn(IFLT, newLabelX);<a name="line.197"></a>
<span class="sourceLineNo">198</span> instrumentJumpHit(true);<a name="line.198"></a>
<span class="sourceLineNo">199</span> mv.visitLabel(newLabelX);<a name="line.199"></a>
<span class="sourceLineNo">200</span> }<a name="line.200"></a>
<span class="sourceLineNo">201</span> } <a name="line.201"></a>
<span class="sourceLineNo">202</span> else if (lastJump != null) <a name="line.202"></a>
<span class="sourceLineNo">203</span> { //this is "only" after jump label, hit the false branch only if the lastJump is same as stored stack lineNumber and jumpNumber<a name="line.203"></a>
<span class="sourceLineNo">204</span> Label newLabelX = instrumentIsLastJump();<a name="line.204"></a>
<span class="sourceLineNo">205</span> instrumentJumpHit(false); <a name="line.205"></a>
<span class="sourceLineNo">206</span> mv.visitLabel(newLabelX);<a name="line.206"></a>
<span class="sourceLineNo">207</span> }<a name="line.207"></a>
<span class="sourceLineNo">208</span> lastJump = null;<a name="line.208"></a>
<span class="sourceLineNo">209</span> <a name="line.209"></a>
<span class="sourceLineNo">210</span> SwitchHolder sh = (SwitchHolder) firstPass.getSwitchTargetLabels().get(label);<a name="line.210"></a>
<span class="sourceLineNo">211</span> if (sh != null)<a name="line.211"></a>
<span class="sourceLineNo">212</span> {<a name="line.212"></a>
<span class="sourceLineNo">213</span> instrumentSwitchHit(sh.getLineNumber(), sh.getSwitchNumber(), sh.getBranch());<a name="line.213"></a>
<span class="sourceLineNo">214</span> }<a name="line.214"></a>
<span class="sourceLineNo">215</span> <a name="line.215"></a>
<span class="sourceLineNo">216</span> //we have to manually invoke the visitLineNumber because of not correct MedthodNode's handling<a name="line.216"></a>
<span class="sourceLineNo">217</span> Integer line = (Integer) firstPass.getLineLabels().get(label);<a name="line.217"></a>
<span class="sourceLineNo">218</span> if (line != null) {<a name="line.218"></a>
<span class="sourceLineNo">219</span> visitLineNumber(line.intValue(), label);<a name="line.219"></a>
<span class="sourceLineNo">220</span> }<a name="line.220"></a>
<span class="sourceLineNo">221</span> }<a name="line.221"></a>
<span class="sourceLineNo">222</span><a name="line.222"></a>
<span class="sourceLineNo">223</span> public void visitLdcInsn(Object cst)<a name="line.223"></a>
<span class="sourceLineNo">224</span> {<a name="line.224"></a>
<span class="sourceLineNo">225</span> //to touch the previous branch (when there is such)<a name="line.225"></a>
<span class="sourceLineNo">226</span> touchBranchFalse();<a name="line.226"></a>
<span class="sourceLineNo">227</span> <a name="line.227"></a>
<span class="sourceLineNo">228</span> super.visitLdcInsn(cst);<a name="line.228"></a>
<span class="sourceLineNo">229</span> }<a name="line.229"></a>
<span class="sourceLineNo">230</span><a name="line.230"></a>
<span class="sourceLineNo">231</span> public void visitMultiANewArrayInsn(String desc, int dims)<a name="line.231"></a>
<span class="sourceLineNo">232</span> {<a name="line.232"></a>
<span class="sourceLineNo">233</span> //to touch the previous branch (when there is such)<a name="line.233"></a>
<span class="sourceLineNo">234</span> touchBranchFalse();<a name="line.234"></a>
<span class="sourceLineNo">235</span> <a name="line.235"></a>
<span class="sourceLineNo">236</span> super.visitMultiANewArrayInsn(desc, dims);<a name="line.236"></a>
<span class="sourceLineNo">237</span> }<a name="line.237"></a>
<span class="sourceLineNo">238</span><a name="line.238"></a>
<span class="sourceLineNo">239</span> public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels)<a name="line.239"></a>
<span class="sourceLineNo">240</span> {<a name="line.240"></a>
<span class="sourceLineNo">241</span> //to touch the previous branch (when there is such)<a name="line.241"></a>
<span class="sourceLineNo">242</span> touchBranchFalse();<a name="line.242"></a>
<span class="sourceLineNo">243</span> <a name="line.243"></a>
<span class="sourceLineNo">244</span> super.visitLookupSwitchInsn(dflt, keys, labels);<a name="line.244"></a>
<span class="sourceLineNo">245</span> }<a name="line.245"></a>
<span class="sourceLineNo">246</span><a name="line.246"></a>
<span class="sourceLineNo">247</span> public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels)<a name="line.247"></a>
<span class="sourceLineNo">248</span> {<a name="line.248"></a>
<span class="sourceLineNo">249</span> //to touch the previous branch (when there is such)<a name="line.249"></a>
<span class="sourceLineNo">250</span> touchBranchFalse();<a name="line.250"></a>
<span class="sourceLineNo">251</span> <a name="line.251"></a>
<span class="sourceLineNo">252</span> super.visitTableSwitchInsn(min, max, dflt, labels);<a name="line.252"></a>
<span class="sourceLineNo">253</span> }<a name="line.253"></a>
<span class="sourceLineNo">254</span><a name="line.254"></a>
<span class="sourceLineNo">255</span> public void visitTryCatchBlock(Label start, Label end, Label handler, String type)<a name="line.255"></a>
<span class="sourceLineNo">256</span> {<a name="line.256"></a>
<span class="sourceLineNo">257</span> //to touch the previous branch (when there is such)<a name="line.257"></a>
<span class="sourceLineNo">258</span> touchBranchFalse();<a name="line.258"></a>
<span class="sourceLineNo">259</span> <a name="line.259"></a>
<span class="sourceLineNo">260</span> super.visitTryCatchBlock(start, end, handler, type);<a name="line.260"></a>
<span class="sourceLineNo">261</span> }<a name="line.261"></a>
<span class="sourceLineNo">262</span><a name="line.262"></a>
<span class="sourceLineNo">263</span> public void visitTypeInsn(int opcode, String desc)<a name="line.263"></a>
<span class="sourceLineNo">264</span> {<a name="line.264"></a>
<span class="sourceLineNo">265</span> //to touch the previous branch (when there is such)<a name="line.265"></a>
<span class="sourceLineNo">266</span> touchBranchFalse();<a name="line.266"></a>
<span class="sourceLineNo">267</span> <a name="line.267"></a>
<span class="sourceLineNo">268</span> super.visitTypeInsn(opcode, desc);<a name="line.268"></a>
<span class="sourceLineNo">269</span> }<a name="line.269"></a>
<span class="sourceLineNo">270</span><a name="line.270"></a>
<span class="sourceLineNo">271</span> public void visitVarInsn(int opcode, int var)<a name="line.271"></a>
<span class="sourceLineNo">272</span> {<a name="line.272"></a>
<span class="sourceLineNo">273</span> //to touch the previous branch (when there is such)<a name="line.273"></a>
<span class="sourceLineNo">274</span> touchBranchFalse();<a name="line.274"></a>
<span class="sourceLineNo">275</span> <a name="line.275"></a>
<span class="sourceLineNo">276</span> //this is to change the variable instructions to conform to 2 new variables<a name="line.276"></a>
<span class="sourceLineNo">277</span> super.visitVarInsn(opcode, var);<a name="line.277"></a>
<span class="sourceLineNo">278</span> }<a name="line.278"></a>
<span class="sourceLineNo">279</span><a name="line.279"></a>
<span class="sourceLineNo">280</span> public void visitCode()<a name="line.280"></a>
<span class="sourceLineNo">281</span> {<a name="line.281"></a>
<span class="sourceLineNo">282</span> methodStarted = true;<a name="line.282"></a>
<span class="sourceLineNo">283</span> super.visitCode();<a name="line.283"></a>
<span class="sourceLineNo">284</span> }<a name="line.284"></a>
<span class="sourceLineNo">285</span> <a name="line.285"></a>
<span class="sourceLineNo">286</span> private void touchBranchFalse() {<a name="line.286"></a>
<span class="sourceLineNo">287</span> if (lastJump != null) {<a name="line.287"></a>
<span class="sourceLineNo">288</span> lastJump = null;<a name="line.288"></a>
<span class="sourceLineNo">289</span> instrumentJumpHit(false);<a name="line.289"></a>
<span class="sourceLineNo">290</span> }<a name="line.290"></a>
<span class="sourceLineNo">291</span> }<a name="line.291"></a>
<span class="sourceLineNo">292</span><a name="line.292"></a>
<span class="sourceLineNo">293</span> private void instrumentOwnerClass()<a name="line.293"></a>
<span class="sourceLineNo">294</span> {<a name="line.294"></a>
<span class="sourceLineNo">295</span> // OwnerClass is the name of the class being instrumented<a name="line.295"></a>
<span class="sourceLineNo">296</span> mv.visitLdcInsn(firstPass.getOwnerClass());<a name="line.296"></a>
<span class="sourceLineNo">297</span> }<a name="line.297"></a>
<span class="sourceLineNo">298</span> <a name="line.298"></a>
<span class="sourceLineNo">299</span> private void instrumentSwitchHit(int lineNumber, int switchNumber, int branch)<a name="line.299"></a>
<span class="sourceLineNo">300</span> {<a name="line.300"></a>
<span class="sourceLineNo">301</span> instrumentOwnerClass();<a name="line.301"></a>
<span class="sourceLineNo">302</span> <a name="line.302"></a>
<span class="sourceLineNo">303</span> //Invoke the touchSwitch(lineNumber, switchNumber, branch)<a name="line.303"></a>
<span class="sourceLineNo">304</span> mv.visitIntInsn(SIPUSH, lineNumber);<a name="line.304"></a>
<span class="sourceLineNo">305</span> mv.visitIntInsn(SIPUSH, switchNumber);<a name="line.305"></a>
<span class="sourceLineNo">306</span> mv.visitIntInsn(SIPUSH, branch);<a name="line.306"></a>
<span class="sourceLineNo">307</span> instrumentInvokeTouchSwitch();<a name="line.307"></a>
<span class="sourceLineNo">308</span> }<a name="line.308"></a>
<span class="sourceLineNo">309</span> <a name="line.309"></a>
<span class="sourceLineNo">310</span> private void instrumentJumpHit(boolean branch)<a name="line.310"></a>
<span class="sourceLineNo">311</span> {<a name="line.311"></a>
<span class="sourceLineNo">312</span> instrumentOwnerClass();<a name="line.312"></a>
<span class="sourceLineNo">313</span> <a name="line.313"></a>
<span class="sourceLineNo">314</span> //Invoke the touchJump(lineNumber, branchNumber, branch)<a name="line.314"></a>
<span class="sourceLineNo">315</span> instrumentPutLineAndBranchNumbers();<a name="line.315"></a>
<span class="sourceLineNo">316</span> mv.visitInsn(branch ? BOOLEAN_TRUE : BOOLEAN_FALSE);<a name="line.316"></a>
<span class="sourceLineNo">317</span> instrumentInvokeTouchJump();<a name="line.317"></a>
<span class="sourceLineNo">318</span> }<a name="line.318"></a>
<span class="sourceLineNo">319</span><a name="line.319"></a>
<span class="sourceLineNo">320</span> private void instrumentInvokeTouchJump()<a name="line.320"></a>
<span class="sourceLineNo">321</span> {<a name="line.321"></a>
<span class="sourceLineNo">322</span> mv.visitMethodInsn(INVOKESTATIC, TOUCH_COLLECTOR_CLASS, "touchJump", "(Ljava/lang/String;IIZ)V");<a name="line.322"></a>
<span class="sourceLineNo">323</span> mv.visitIntInsn(SIPUSH, -1); //is important to reset current branch, because we have to know that the branch info on stack has already been used and can't be used<a name="line.323"></a>
<span class="sourceLineNo">324</span> mv.visitVarInsn(ISTORE, myVariableIndex + 1);<a name="line.324"></a>
<span class="sourceLineNo">325</span> }<a name="line.325"></a>
<span class="sourceLineNo">326</span><a name="line.326"></a>
<span class="sourceLineNo">327</span> private void instrumentInvokeTouchSwitch()<a name="line.327"></a>
<span class="sourceLineNo">328</span> {<a name="line.328"></a>
<span class="sourceLineNo">329</span> mv.visitMethodInsn(INVOKESTATIC, TOUCH_COLLECTOR_CLASS, "touchSwitch", "(Ljava/lang/String;III)V");<a name="line.329"></a>
<span class="sourceLineNo">330</span> }<a name="line.330"></a>
<span class="sourceLineNo">331</span><a name="line.331"></a>
<span class="sourceLineNo">332</span> private void instrumentPutLineAndBranchNumbers()<a name="line.332"></a>
<span class="sourceLineNo">333</span> {<a name="line.333"></a>
<span class="sourceLineNo">334</span> mv.visitVarInsn(ILOAD, myVariableIndex);<a name="line.334"></a>
<span class="sourceLineNo">335</span> mv.visitVarInsn(ILOAD, myVariableIndex + 1);<a name="line.335"></a>
<span class="sourceLineNo">336</span> }<a name="line.336"></a>
<span class="sourceLineNo">337</span><a name="line.337"></a>
<span class="sourceLineNo">338</span> private Label instrumentIsLastJump() {<a name="line.338"></a>
<span class="sourceLineNo">339</span> mv.visitVarInsn(ILOAD, myVariableIndex);<a name="line.339"></a>
<span class="sourceLineNo">340</span> mv.visitIntInsn(SIPUSH, lastJump.getLineNumber());<a name="line.340"></a>
<span class="sourceLineNo">341</span> Label newLabelX = new Label();<a name="line.341"></a>
<span class="sourceLineNo">342</span> mv.visitJumpInsn(IF_ICMPNE, newLabelX);<a name="line.342"></a>
<span class="sourceLineNo">343</span> mv.visitVarInsn(ILOAD, myVariableIndex + 1);<a name="line.343"></a>
<span class="sourceLineNo">344</span> mv.visitIntInsn(SIPUSH, lastJump.getJumpNumber());<a name="line.344"></a>
<span class="sourceLineNo">345</span> mv.visitJumpInsn(IF_ICMPNE, newLabelX);<a name="line.345"></a>
<span class="sourceLineNo">346</span> return newLabelX;<a name="line.346"></a>
<span class="sourceLineNo">347</span> }<a name="line.347"></a>
<span class="sourceLineNo">348</span><a name="line.348"></a>
<span class="sourceLineNo">349</span> public void visitMaxs(int maxStack, int maxLocals)<a name="line.349"></a>
<span class="sourceLineNo">350</span> {<a name="line.350"></a>
<span class="sourceLineNo">351</span> mv.visitLocalVariable("__cobertura__line__number__", "I", null, startLabel, endLabel, myVariableIndex);<a name="line.351"></a>
<span class="sourceLineNo">352</span> mv.visitLocalVariable("__cobertura__branch__number__", "I", null, startLabel, endLabel, myVariableIndex + 1);<a name="line.352"></a>
<span class="sourceLineNo">353</span> super.visitMaxs(maxStack, maxLocals);<a name="line.353"></a>
<span class="sourceLineNo">354</span> }<a name="line.354"></a>
<span class="sourceLineNo">355</span><a name="line.355"></a>
<span class="sourceLineNo">356</span>}<a name="line.356"></a>
</pre>
</div>
</body>
</html>
|