Instrumenter.java
1/*******************************************************************************
2 * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
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 * Marc R. Hoffmann - initial API and implementation
10 *
11 * $Id: $
12 *******************************************************************************/
13package org.jacoco.core.instr;
14
15import org.jacoco.core.runtime.IRuntime;
16import org.objectweb.asm.ClassReader;
17import org.objectweb.asm.ClassVisitor;
18import org.objectweb.asm.ClassWriter;
19import org.objectweb.asm.Opcodes;
20
21/**
22 * Several APIs to instrument Java class definitions for coverage tracing.
23 *
24 * @author Marc R. Hoffmann
25 * @version $Revision: $
26 */
27public class Instrumenter {
28
29 private final IRuntime runtime;
30
31 /**
32 * Creates a new instance based on the given runtime.
33 *
34 * @param runtime
35 * runtime used by the instrumented classes
36 */
37 public Instrumenter(final IRuntime runtime) {
38 this.runtime = runtime;
39 }
40
41 /**
42 * Creates a ASM adapter for a class with the given id.
43 *
44 * @param classid
45 * id of the class calculated with {@link CRC64}
46 * @param cv
47 * next class visitor in the chain
48 * @return new visitor to write class definition to
49 */
50 public ClassVisitor createInstrumentingVisitor(final long classid,
51 final ClassVisitor cv) {
52 return new ClassInstrumenter(classid, runtime, cv);
53 }
54
55 /**
56 * Creates a instrumented version of the given class if possible.
57 *
58 * @param reader
59 * definition of the class as ASM reader
60 * @return instrumented definition or <code>null</code>
61 *
62 */
63 public byte[] instrument(final ClassReader reader) {
64
65 // Don't instrument interfaces
66 if ((reader.getAccess() & Opcodes.ACC_INTERFACE) != 0) {
67 return null;
68 }
69
70 final ClassWriter writer = new ClassWriter(reader, 0);
71 final ClassVisitor visitor = createInstrumentingVisitor(CRC64
72 .checksum(reader.b), writer);
73 reader.accept(visitor, ClassReader.EXPAND_FRAMES);
74 return writer.toByteArray();
75 }
76
77 /**
78 * Creates a instrumented version of the given class if possible.
79 *
80 * @param buffer
81 * definition of the class
82 * @return instrumented definition or <code>null</code>
83 *
84 */
85 public byte[] instrument(final byte[] buffer) {
86 return instrument(new ClassReader(buffer));
87 }
88
89}