• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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