1/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation.  Oracle designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Oracle in the LICENSE file that accompanied this code.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25/*
26 * This file is available under and governed by the GNU General Public
27 * License version 2 only, as published by the Free Software Foundation.
28 * However, the following notice accompanied the original version of this
29 * file:
30 *
31 * ASM: a very small and fast Java bytecode manipulation framework
32 * Copyright (c) 2000-2011 INRIA, France Telecom
33 * All rights reserved.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 * 1. Redistributions of source code must retain the above copyright
39 *    notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 *    notice, this list of conditions and the following disclaimer in the
42 *    documentation and/or other materials provided with the distribution.
43 * 3. Neither the name of the copyright holders nor the names of its
44 *    contributors may be used to endorse or promote products derived from
45 *    this software without specific prior written permission.
46 *
47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
48 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
51 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
52 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
53 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
55 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
57 * THE POSSIBILITY OF SUCH DAMAGE.
58 */
59package jdk.internal.org.objectweb.asm.util;
60
61import jdk.internal.org.objectweb.asm.AnnotationVisitor;
62import jdk.internal.org.objectweb.asm.Attribute;
63import jdk.internal.org.objectweb.asm.Handle;
64import jdk.internal.org.objectweb.asm.Label;
65import jdk.internal.org.objectweb.asm.MethodVisitor;
66import jdk.internal.org.objectweb.asm.Opcodes;
67import jdk.internal.org.objectweb.asm.TypePath;
68
69/**
70 * A {@link MethodVisitor} that prints the methods it visits with a
71 * {@link Printer}.
72 *
73 * @author Eric Bruneton
74 */
75public final class TraceMethodVisitor extends MethodVisitor {
76
77    public final Printer p;
78
79    public TraceMethodVisitor(final Printer p) {
80        this(null, p);
81    }
82
83    public TraceMethodVisitor(final MethodVisitor mv, final Printer p) {
84        super(Opcodes.ASM5, mv);
85        this.p = p;
86    }
87
88    @Override
89    public void visitParameter(String name, int access) {
90        p.visitParameter(name, access);
91        super.visitParameter(name, access);
92    }
93
94    @Override
95    public AnnotationVisitor visitAnnotation(final String desc,
96            final boolean visible) {
97        Printer p = this.p.visitMethodAnnotation(desc, visible);
98        AnnotationVisitor av = mv == null ? null : mv.visitAnnotation(desc,
99                visible);
100        return new TraceAnnotationVisitor(av, p);
101    }
102
103    @Override
104    public AnnotationVisitor visitTypeAnnotation(int typeRef,
105            TypePath typePath, String desc, boolean visible) {
106        Printer p = this.p.visitMethodTypeAnnotation(typeRef, typePath, desc,
107                visible);
108        AnnotationVisitor av = mv == null ? null : mv.visitTypeAnnotation(
109                typeRef, typePath, desc, visible);
110        return new TraceAnnotationVisitor(av, p);
111    }
112
113    @Override
114    public void visitAttribute(final Attribute attr) {
115        p.visitMethodAttribute(attr);
116        super.visitAttribute(attr);
117    }
118
119    @Override
120    public AnnotationVisitor visitAnnotationDefault() {
121        Printer p = this.p.visitAnnotationDefault();
122        AnnotationVisitor av = mv == null ? null : mv.visitAnnotationDefault();
123        return new TraceAnnotationVisitor(av, p);
124    }
125
126    @Override
127    public AnnotationVisitor visitParameterAnnotation(final int parameter,
128            final String desc, final boolean visible) {
129        Printer p = this.p.visitParameterAnnotation(parameter, desc, visible);
130        AnnotationVisitor av = mv == null ? null : mv.visitParameterAnnotation(
131                parameter, desc, visible);
132        return new TraceAnnotationVisitor(av, p);
133    }
134
135    @Override
136    public void visitCode() {
137        p.visitCode();
138        super.visitCode();
139    }
140
141    @Override
142    public void visitFrame(final int type, final int nLocal,
143            final Object[] local, final int nStack, final Object[] stack) {
144        p.visitFrame(type, nLocal, local, nStack, stack);
145        super.visitFrame(type, nLocal, local, nStack, stack);
146    }
147
148    @Override
149    public void visitInsn(final int opcode) {
150        p.visitInsn(opcode);
151        super.visitInsn(opcode);
152    }
153
154    @Override
155    public void visitIntInsn(final int opcode, final int operand) {
156        p.visitIntInsn(opcode, operand);
157        super.visitIntInsn(opcode, operand);
158    }
159
160    @Override
161    public void visitVarInsn(final int opcode, final int var) {
162        p.visitVarInsn(opcode, var);
163        super.visitVarInsn(opcode, var);
164    }
165
166    @Override
167    public void visitTypeInsn(final int opcode, final String type) {
168        p.visitTypeInsn(opcode, type);
169        super.visitTypeInsn(opcode, type);
170    }
171
172    @Override
173    public void visitFieldInsn(final int opcode, final String owner,
174            final String name, final String desc) {
175        p.visitFieldInsn(opcode, owner, name, desc);
176        super.visitFieldInsn(opcode, owner, name, desc);
177    }
178
179    @Deprecated
180    @Override
181    public void visitMethodInsn(int opcode, String owner, String name,
182            String desc) {
183        if (api >= Opcodes.ASM5) {
184            super.visitMethodInsn(opcode, owner, name, desc);
185            return;
186        }
187        p.visitMethodInsn(opcode, owner, name, desc);
188        if (mv != null) {
189            mv.visitMethodInsn(opcode, owner, name, desc);
190        }
191    }
192
193    @Override
194    public void visitMethodInsn(int opcode, String owner, String name,
195            String desc, boolean itf) {
196        if (api < Opcodes.ASM5) {
197            super.visitMethodInsn(opcode, owner, name, desc, itf);
198            return;
199        }
200        p.visitMethodInsn(opcode, owner, name, desc, itf);
201        if (mv != null) {
202            mv.visitMethodInsn(opcode, owner, name, desc, itf);
203        }
204    }
205
206    @Override
207    public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
208            Object... bsmArgs) {
209        p.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
210        super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
211    }
212
213    @Override
214    public void visitJumpInsn(final int opcode, final Label label) {
215        p.visitJumpInsn(opcode, label);
216        super.visitJumpInsn(opcode, label);
217    }
218
219    @Override
220    public void visitLabel(final Label label) {
221        p.visitLabel(label);
222        super.visitLabel(label);
223    }
224
225    @Override
226    public void visitLdcInsn(final Object cst) {
227        p.visitLdcInsn(cst);
228        super.visitLdcInsn(cst);
229    }
230
231    @Override
232    public void visitIincInsn(final int var, final int increment) {
233        p.visitIincInsn(var, increment);
234        super.visitIincInsn(var, increment);
235    }
236
237    @Override
238    public void visitTableSwitchInsn(final int min, final int max,
239            final Label dflt, final Label... labels) {
240        p.visitTableSwitchInsn(min, max, dflt, labels);
241        super.visitTableSwitchInsn(min, max, dflt, labels);
242    }
243
244    @Override
245    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
246            final Label[] labels) {
247        p.visitLookupSwitchInsn(dflt, keys, labels);
248        super.visitLookupSwitchInsn(dflt, keys, labels);
249    }
250
251    @Override
252    public void visitMultiANewArrayInsn(final String desc, final int dims) {
253        p.visitMultiANewArrayInsn(desc, dims);
254        super.visitMultiANewArrayInsn(desc, dims);
255    }
256
257    @Override
258    public AnnotationVisitor visitInsnAnnotation(int typeRef,
259            TypePath typePath, String desc, boolean visible) {
260        Printer p = this.p
261                .visitInsnAnnotation(typeRef, typePath, desc, visible);
262        AnnotationVisitor av = mv == null ? null : mv.visitInsnAnnotation(
263                typeRef, typePath, desc, visible);
264        return new TraceAnnotationVisitor(av, p);
265    }
266
267    @Override
268    public void visitTryCatchBlock(final Label start, final Label end,
269            final Label handler, final String type) {
270        p.visitTryCatchBlock(start, end, handler, type);
271        super.visitTryCatchBlock(start, end, handler, type);
272    }
273
274    @Override
275    public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
276            TypePath typePath, String desc, boolean visible) {
277        Printer p = this.p.visitTryCatchAnnotation(typeRef, typePath, desc,
278                visible);
279        AnnotationVisitor av = mv == null ? null : mv.visitTryCatchAnnotation(
280                typeRef, typePath, desc, visible);
281        return new TraceAnnotationVisitor(av, p);
282    }
283
284    @Override
285    public void visitLocalVariable(final String name, final String desc,
286            final String signature, final Label start, final Label end,
287            final int index) {
288        p.visitLocalVariable(name, desc, signature, start, end, index);
289        super.visitLocalVariable(name, desc, signature, start, end, index);
290    }
291
292    @Override
293    public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
294            TypePath typePath, Label[] start, Label[] end, int[] index,
295            String desc, boolean visible) {
296        Printer p = this.p.visitLocalVariableAnnotation(typeRef, typePath,
297                start, end, index, desc, visible);
298        AnnotationVisitor av = mv == null ? null : mv
299                .visitLocalVariableAnnotation(typeRef, typePath, start, end,
300                        index, desc, visible);
301        return new TraceAnnotationVisitor(av, p);
302    }
303
304    @Override
305    public void visitLineNumber(final int line, final Label start) {
306        p.visitLineNumber(line, start);
307        super.visitLineNumber(line, start);
308    }
309
310    @Override
311    public void visitMaxs(final int maxStack, final int maxLocals) {
312        p.visitMaxs(maxStack, maxLocals);
313        super.visitMaxs(maxStack, maxLocals);
314    }
315
316    @Override
317    public void visitEnd() {
318        p.visitMethodEnd();
319        super.visitEnd();
320    }
321}
322