aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java
blob: 6cea48c6720997cfc0f9f29b669ec9eedfca092b (plain)
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
/*******************************************************************************
 * Copyright (c) 2009, 2016 Mountainminds GmbH & Co. KG and Contributors
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Marc R. Hoffmann - initial API and implementation
 *    
 *******************************************************************************/
package org.jacoco.core.internal.instr;

import org.jacoco.core.internal.flow.ClassProbesVisitor;
import org.jacoco.core.internal.flow.MethodProbesVisitor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;

/**
 * Adapter that instruments a class for coverage tracing.
 */
public class ClassInstrumenter extends ClassProbesVisitor {

	private final IProbeArrayStrategy probeArrayStrategy;

	private String className;

	/**
	 * Emits a instrumented version of this class to the given class visitor.
	 * 
	 * @param probeArrayStrategy
	 *            this strategy will be used to access the probe array
	 * @param cv
	 *            next delegate in the visitor chain will receive the
	 *            instrumented class
	 */
	public ClassInstrumenter(final IProbeArrayStrategy probeArrayStrategy,
			final ClassVisitor cv) {
		super(cv);
		this.probeArrayStrategy = probeArrayStrategy;
	}

	@Override
	public void visit(final int version, final int access, final String name,
			final String signature, final String superName,
			final String[] interfaces) {
		this.className = name;
		super.visit(version, access, name, signature, superName, interfaces);
	}

	@Override
	public FieldVisitor visitField(final int access, final String name,
			final String desc, final String signature, final Object value) {
		InstrSupport.assertNotInstrumented(name, className);
		return super.visitField(access, name, desc, signature, value);
	}

	@Override
	public MethodProbesVisitor visitMethod(final int access, final String name,
			final String desc, final String signature, final String[] exceptions) {

		InstrSupport.assertNotInstrumented(name, className);

		final MethodVisitor mv = cv.visitMethod(access, name, desc, signature,
				exceptions);

		if (mv == null) {
			return null;
		}
		final MethodVisitor frameEliminator = new DuplicateFrameEliminator(mv);
		final ProbeInserter probeVariableInserter = new ProbeInserter(access,
				desc, frameEliminator, probeArrayStrategy);
		return new MethodInstrumenter(probeVariableInserter,
				probeVariableInserter);
	}

	@Override
	public void visitTotalProbeCount(final int count) {
		probeArrayStrategy.addMembers(cv, count);
	}

}