1/******************************************************************************* 2 * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * Evgeny Mandrikov - initial API and implementation 10 * 11 *******************************************************************************/ 12package org.jacoco.core.internal.analysis.filter; 13 14import static org.junit.Assert.assertEquals; 15import static org.junit.Assert.assertNull; 16 17import org.jacoco.core.internal.instr.InstrSupport; 18import org.junit.Test; 19import org.objectweb.asm.Label; 20import org.objectweb.asm.Opcodes; 21import org.objectweb.asm.tree.AbstractInsnNode; 22import org.objectweb.asm.tree.LabelNode; 23import org.objectweb.asm.tree.MethodNode; 24 25public class SynchronizedFilterTest implements IFilterOutput { 26 27 private final SynchronizedFilter filter = new SynchronizedFilter(); 28 29 private final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, 30 "name", "()V", null, null); 31 32 private AbstractInsnNode fromInclusive; 33 private AbstractInsnNode toInclusive; 34 35 @Test 36 public void javac() { 37 final Label start = new Label(); 38 final Label end = new Label(); 39 final Label handler = new Label(); 40 final Label handlerEnd = new Label(); 41 m.visitTryCatchBlock(start, end, handler, null); 42 m.visitTryCatchBlock(handler, handlerEnd, handler, null); 43 44 m.visitVarInsn(Opcodes.ALOAD, 0); 45 m.visitFieldInsn(Opcodes.GETFIELD, "Fun", "lock", "Ljava/lang/Object;"); 46 m.visitInsn(Opcodes.DUP); 47 m.visitVarInsn(Opcodes.ASTORE, 1); 48 m.visitInsn(Opcodes.MONITORENTER); 49 m.visitLabel(start); 50 m.visitInsn(Opcodes.NOP); 51 m.visitVarInsn(Opcodes.ALOAD, 1); 52 m.visitInsn(Opcodes.MONITOREXIT); 53 m.visitLabel(end); 54 final Label exit = new Label(); 55 m.visitJumpInsn(Opcodes.GOTO, exit); 56 m.visitLabel(handler); 57 m.visitVarInsn(Opcodes.ASTORE, 2); 58 m.visitVarInsn(Opcodes.ALOAD, 1); 59 m.visitInsn(Opcodes.MONITOREXIT); 60 m.visitLabel(handlerEnd); 61 m.visitVarInsn(Opcodes.ALOAD, 2); 62 m.visitInsn(Opcodes.ATHROW); 63 m.visitLabel(exit); 64 m.visitInsn(Opcodes.RETURN); 65 66 filter.filter("Foo", "java/lang/Object", m, this); 67 assertEquals(handler.info, fromInclusive); 68 assertEquals(((LabelNode) exit.info).getPrevious(), toInclusive); 69 } 70 71 /** 72 * <pre> 73 * try { 74 * ... 75 * } catch (Exception e) { 76 * ... 77 * } finally { 78 * ... 79 * } 80 * </pre> 81 */ 82 @Test 83 public void javacTryCatchFinally() { 84 final Label start = new Label(); 85 final Label end = new Label(); 86 final Label catchHandler = new Label(); 87 final Label finallyHandler = new Label(); 88 final Label catchHandlerEnd = new Label(); 89 m.visitTryCatchBlock(start, end, catchHandler, "java/lang/Exception"); 90 m.visitTryCatchBlock(start, end, finallyHandler, null); 91 m.visitTryCatchBlock(catchHandler, catchHandlerEnd, finallyHandler, 92 null); 93 94 m.visitLabel(start); 95 // body 96 m.visitInsn(Opcodes.NOP); 97 m.visitLabel(end); 98 // finally 99 m.visitInsn(Opcodes.NOP); 100 final Label exit = new Label(); 101 m.visitJumpInsn(Opcodes.GOTO, exit); 102 m.visitLabel(catchHandler); 103 m.visitVarInsn(Opcodes.ASTORE, 1); 104 // catch 105 m.visitInsn(Opcodes.NOP); 106 m.visitLabel(catchHandlerEnd); 107 // finally 108 m.visitInsn(Opcodes.NOP); 109 m.visitJumpInsn(Opcodes.GOTO, exit); 110 m.visitLabel(finallyHandler); 111 m.visitVarInsn(Opcodes.ASTORE, 2); 112 // finally 113 m.visitInsn(Opcodes.NOP); 114 m.visitVarInsn(Opcodes.ALOAD, 2); 115 m.visitInsn(Opcodes.ATHROW); 116 m.visitLabel(exit); 117 m.visitInsn(Opcodes.RETURN); 118 119 filter.filter("Foo", "java/lang/Object", m, this); 120 assertNull(fromInclusive); 121 } 122 123 @Test 124 public void ecj() { 125 final Label start = new Label(); 126 final Label end = new Label(); 127 final Label handler = new Label(); 128 final Label handlerEnd = new Label(); 129 m.visitTryCatchBlock(start, end, handler, null); 130 m.visitTryCatchBlock(handler, handlerEnd, handler, null); 131 132 m.visitVarInsn(Opcodes.ALOAD, 0); 133 m.visitFieldInsn(Opcodes.GETFIELD, "Target", "lock", 134 "Ljava/lang/Object;"); 135 m.visitInsn(Opcodes.DUP); 136 m.visitVarInsn(Opcodes.ASTORE, 1); 137 m.visitInsn(Opcodes.MONITORENTER); 138 m.visitLabel(start); 139 m.visitVarInsn(Opcodes.ALOAD, 0); 140 m.visitInsn(Opcodes.NOP); 141 m.visitVarInsn(Opcodes.ALOAD, 1); 142 m.visitInsn(Opcodes.MONITOREXIT); 143 m.visitLabel(end); 144 final Label exit = new Label(); 145 m.visitJumpInsn(Opcodes.GOTO, exit); 146 m.visitLabel(handler); 147 m.visitVarInsn(Opcodes.ALOAD, 1); 148 m.visitInsn(Opcodes.MONITOREXIT); 149 m.visitLabel(handlerEnd); 150 m.visitInsn(Opcodes.ATHROW); 151 m.visitLabel(exit); 152 m.visitInsn(Opcodes.RETURN); 153 154 filter.filter("Foo", "java/lang/Object", m, this); 155 assertEquals(handler.info, fromInclusive); 156 assertEquals(((LabelNode) exit.info).getPrevious(), toInclusive); 157 } 158 159 public void ignore(AbstractInsnNode fromInclusive, 160 AbstractInsnNode toInclusive) { 161 assertNull(this.fromInclusive); 162 this.fromInclusive = fromInclusive; 163 this.toInclusive = toInclusive; 164 } 165 166} 167