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