1 /******************************************************************************* 2 * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors 3 * This program and the accompanying materials are made available under 4 * the terms of the Eclipse Public License 2.0 which is available at 5 * http://www.eclipse.org/legal/epl-2.0 6 * 7 * SPDX-License-Identifier: EPL-2.0 8 * 9 * Contributors: 10 * Marc R. Hoffmann - initial API and implementation 11 * 12 *******************************************************************************/ 13 package org.jacoco.core.internal.instr; 14 15 import org.jacoco.core.internal.flow.ClassProbesVisitor; 16 import org.jacoco.core.internal.flow.MethodProbesVisitor; 17 import org.objectweb.asm.ClassVisitor; 18 import org.objectweb.asm.FieldVisitor; 19 import org.objectweb.asm.MethodVisitor; 20 21 /** 22 * Adapter that instruments a class for coverage tracing. 23 */ 24 public class ClassInstrumenter extends ClassProbesVisitor { 25 26 private final IProbeArrayStrategy probeArrayStrategy; 27 28 private String className; 29 30 /** 31 * Emits a instrumented version of this class to the given class visitor. 32 * 33 * @param probeArrayStrategy 34 * this strategy will be used to access the probe array 35 * @param cv 36 * next delegate in the visitor chain will receive the 37 * instrumented class 38 */ ClassInstrumenter(final IProbeArrayStrategy probeArrayStrategy, final ClassVisitor cv)39 public ClassInstrumenter(final IProbeArrayStrategy probeArrayStrategy, 40 final ClassVisitor cv) { 41 super(cv); 42 this.probeArrayStrategy = probeArrayStrategy; 43 } 44 45 @Override visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces)46 public void visit(final int version, final int access, final String name, 47 final String signature, final String superName, 48 final String[] interfaces) { 49 this.className = name; 50 super.visit(version, access, name, signature, superName, interfaces); 51 } 52 53 @Override visitField(final int access, final String name, final String desc, final String signature, final Object value)54 public FieldVisitor visitField(final int access, final String name, 55 final String desc, final String signature, final Object value) { 56 InstrSupport.assertNotInstrumented(name, className); 57 return super.visitField(access, name, desc, signature, value); 58 } 59 60 @Override visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions)61 public MethodProbesVisitor visitMethod(final int access, final String name, 62 final String desc, final String signature, 63 final String[] exceptions) { 64 65 InstrSupport.assertNotInstrumented(name, className); 66 67 final MethodVisitor mv = cv.visitMethod(access, name, desc, signature, 68 exceptions); 69 70 if (mv == null) { 71 return null; 72 } 73 final MethodVisitor frameEliminator = new DuplicateFrameEliminator(mv); 74 final ProbeInserter probeVariableInserter = new ProbeInserter(access, 75 name, desc, frameEliminator, probeArrayStrategy); 76 return new MethodInstrumenter(probeVariableInserter, 77 probeVariableInserter); 78 } 79 80 @Override visitTotalProbeCount(final int count)81 public void visitTotalProbeCount(final int count) { 82 probeArrayStrategy.addMembers(cv, count); 83 } 84 85 } 86