MethodAnalyzer.java
1/*******************************************************************************
2 * Copyright (c) 2009, 2010 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 * Marc R. Hoffmann - initial API and implementation
10 *
11 * $Id: $
12 *******************************************************************************/
13package org.jacoco.core.instr;
14
15import org.jacoco.core.data.IMethodStructureVisitor;
16import org.objectweb.asm.AnnotationVisitor;
17import org.objectweb.asm.Attribute;
18import org.objectweb.asm.Label;
19
20/**
21 * This {@link IBlockMethodVisitor} analyzes the block structure of a method and
22 * reports it to a {@link IMethodStructureVisitor} instance.
23 *
24 * @author Marc R. Hoffmann
25 * @version $Revision: $
26 */
27public final class MethodAnalyzer implements IBlockMethodVisitor {
28
29 private static final int NO_LINE_INFO = -1;
30
31 private final IMethodStructureVisitor structureVisitor;
32
33 private int instructionCount;
34
35 private int currentLine;
36
37 private final IntSet lineNumbers;
38
39 /**
40 * Creates a new analyzer that reports to the given
41 * {@link IMethodStructureVisitor} instance.
42 *
43 * @param structureVisitor
44 * consumer for method structure events
45 */
46 public MethodAnalyzer(final IMethodStructureVisitor structureVisitor) {
47 this.structureVisitor = structureVisitor;
48 this.instructionCount = 0;
49 this.currentLine = NO_LINE_INFO;
50 this.lineNumbers = new IntSet();
51 }
52
53 private void addInstruction() {
54 instructionCount++;
55 if (currentLine != NO_LINE_INFO) {
56 lineNumbers.add(currentLine);
57 }
58 }
59
60 // === MethodVisitor ===
61
62 public AnnotationVisitor visitAnnotation(final String desc,
63 final boolean visible) {
64 return null;
65 }
66
67 public AnnotationVisitor visitAnnotationDefault() {
68 return null;
69 }
70
71 public AnnotationVisitor visitParameterAnnotation(final int parameter,
72 final String desc, final boolean visible) {
73 return null;
74 }
75
76 public void visitAttribute(final Attribute attr) {
77 }
78
79 public void visitCode() {
80 }
81
82 public void visitFrame(final int type, final int local,
83 final Object[] local2, final int stack, final Object[] stack2) {
84 }
85
86 public void visitLabel(final Label label) {
87 }
88
89 public void visitLocalVariable(final String name, final String desc,
90 final String signature, final Label start, final Label end,
91 final int index) {
92 }
93
94 public void visitTryCatchBlock(final Label start, final Label end,
95 final Label handler, final String type) {
96 }
97
98 public void visitMaxs(final int maxStack, final int maxLocals) {
99 }
100
101 public void visitLineNumber(final int line, final Label start) {
102 currentLine = line;
103 }
104
105 public void visitInsn(final int opcode) {
106 addInstruction();
107 }
108
109 public void visitJumpInsn(final int opcode, final Label label) {
110 addInstruction();
111 }
112
113 public void visitFieldInsn(final int opcode, final String owner,
114 final String name, final String desc) {
115 addInstruction();
116 }
117
118 public void visitIincInsn(final int var, final int increment) {
119 addInstruction();
120 }
121
122 public void visitIntInsn(final int opcode, final int operand) {
123 addInstruction();
124 }
125
126 public void visitLdcInsn(final Object cst) {
127 addInstruction();
128 }
129
130 public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
131 final Label[] labels) {
132 addInstruction();
133 }
134
135 public void visitMethodInsn(final int opcode, final String owner,
136 final String name, final String desc) {
137 addInstruction();
138 }
139
140 public void visitMultiANewArrayInsn(final String desc, final int dims) {
141 addInstruction();
142 }
143
144 public void visitTableSwitchInsn(final int min, final int max,
145 final Label dflt, final Label[] labels) {
146 addInstruction();
147 }
148
149 public void visitTypeInsn(final int opcode, final String type) {
150 addInstruction();
151 }
152
153 public void visitVarInsn(final int opcode, final int var) {
154 addInstruction();
155 }
156
157 public void visitEnd() {
158 structureVisitor.visitEnd();
159 }
160
161 // === IBlockVisitor ===
162
163 public void visitBlockEndBeforeJump(final int id) {
164 }
165
166 public void visitBlockEnd(final int id) {
167 structureVisitor.block(id, instructionCount, lineNumbers.toArray());
168 instructionCount = 0;
169 lineNumbers.clear();
170 }
171
172}