• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // ASM: a very small and fast Java bytecode manipulation framework
2 // Copyright (c) 2000-2011 INRIA, France Telecom
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions
7 // are met:
8 // 1. Redistributions of source code must retain the above copyright
9 //    notice, this list of conditions and the following disclaimer.
10 // 2. Redistributions in binary form must reproduce the above copyright
11 //    notice, this list of conditions and the following disclaimer in the
12 //    documentation and/or other materials provided with the distribution.
13 // 3. Neither the name of the copyright holders nor the names of its
14 //    contributors may be used to endorse or promote products derived from
15 //    this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 // THE POSSIBILITY OF SUCH DAMAGE.
28 package org.objectweb.asm.util;
29 
30 import org.objectweb.asm.AnnotationVisitor;
31 import org.objectweb.asm.Attribute;
32 import org.objectweb.asm.Handle;
33 import org.objectweb.asm.Label;
34 import org.objectweb.asm.MethodVisitor;
35 import org.objectweb.asm.Opcodes;
36 import org.objectweb.asm.TypePath;
37 
38 /**
39  * A {@link MethodVisitor} that prints the methods it visits with a {@link Printer}.
40  *
41  * @author Eric Bruneton
42  */
43 public final class TraceMethodVisitor extends MethodVisitor {
44 
45   /** The printer to convert the visited method into text. */
46   // DontCheck(MemberName): can't be renamed (for backward binary compatibility).
47   public final Printer p;
48 
49   /**
50    * Constructs a new {@link TraceMethodVisitor}.
51    *
52    * @param printer the printer to convert the visited method into text.
53    */
TraceMethodVisitor(final Printer printer)54   public TraceMethodVisitor(final Printer printer) {
55     this(null, printer);
56   }
57 
58   /**
59    * Constructs a new {@link TraceMethodVisitor}.
60    *
61    * @param methodVisitor the method visitor to which to delegate calls. May be {@literal null}.
62    * @param printer the printer to convert the visited method into text.
63    */
TraceMethodVisitor(final MethodVisitor methodVisitor, final Printer printer)64   public TraceMethodVisitor(final MethodVisitor methodVisitor, final Printer printer) {
65     super(/* latest api = */ Opcodes.ASM9, methodVisitor);
66     this.p = printer;
67   }
68 
69   @Override
visitParameter(final String name, final int access)70   public void visitParameter(final String name, final int access) {
71     p.visitParameter(name, access);
72     super.visitParameter(name, access);
73   }
74 
75   @Override
visitAnnotation(final String descriptor, final boolean visible)76   public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
77     Printer annotationPrinter = p.visitMethodAnnotation(descriptor, visible);
78     return new TraceAnnotationVisitor(
79         super.visitAnnotation(descriptor, visible), annotationPrinter);
80   }
81 
82   @Override
visitTypeAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible)83   public AnnotationVisitor visitTypeAnnotation(
84       final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
85     Printer annotationPrinter = p.visitMethodTypeAnnotation(typeRef, typePath, descriptor, visible);
86     return new TraceAnnotationVisitor(
87         super.visitTypeAnnotation(typeRef, typePath, descriptor, visible), annotationPrinter);
88   }
89 
90   @Override
visitAttribute(final Attribute attribute)91   public void visitAttribute(final Attribute attribute) {
92     p.visitMethodAttribute(attribute);
93     super.visitAttribute(attribute);
94   }
95 
96   @Override
visitAnnotationDefault()97   public AnnotationVisitor visitAnnotationDefault() {
98     Printer annotationPrinter = p.visitAnnotationDefault();
99     return new TraceAnnotationVisitor(super.visitAnnotationDefault(), annotationPrinter);
100   }
101 
102   @Override
visitAnnotableParameterCount(final int parameterCount, final boolean visible)103   public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
104     p.visitAnnotableParameterCount(parameterCount, visible);
105     super.visitAnnotableParameterCount(parameterCount, visible);
106   }
107 
108   @Override
visitParameterAnnotation( final int parameter, final String descriptor, final boolean visible)109   public AnnotationVisitor visitParameterAnnotation(
110       final int parameter, final String descriptor, final boolean visible) {
111     Printer annotationPrinter = p.visitParameterAnnotation(parameter, descriptor, visible);
112     return new TraceAnnotationVisitor(
113         super.visitParameterAnnotation(parameter, descriptor, visible), annotationPrinter);
114   }
115 
116   @Override
visitCode()117   public void visitCode() {
118     p.visitCode();
119     super.visitCode();
120   }
121 
122   @Override
visitFrame( final int type, final int numLocal, final Object[] local, final int numStack, final Object[] stack)123   public void visitFrame(
124       final int type,
125       final int numLocal,
126       final Object[] local,
127       final int numStack,
128       final Object[] stack) {
129     p.visitFrame(type, numLocal, local, numStack, stack);
130     super.visitFrame(type, numLocal, local, numStack, stack);
131   }
132 
133   @Override
visitInsn(final int opcode)134   public void visitInsn(final int opcode) {
135     p.visitInsn(opcode);
136     super.visitInsn(opcode);
137   }
138 
139   @Override
visitIntInsn(final int opcode, final int operand)140   public void visitIntInsn(final int opcode, final int operand) {
141     p.visitIntInsn(opcode, operand);
142     super.visitIntInsn(opcode, operand);
143   }
144 
145   @Override
visitVarInsn(final int opcode, final int varIndex)146   public void visitVarInsn(final int opcode, final int varIndex) {
147     p.visitVarInsn(opcode, varIndex);
148     super.visitVarInsn(opcode, varIndex);
149   }
150 
151   @Override
visitTypeInsn(final int opcode, final String type)152   public void visitTypeInsn(final int opcode, final String type) {
153     p.visitTypeInsn(opcode, type);
154     super.visitTypeInsn(opcode, type);
155   }
156 
157   @Override
visitFieldInsn( final int opcode, final String owner, final String name, final String descriptor)158   public void visitFieldInsn(
159       final int opcode, final String owner, final String name, final String descriptor) {
160     p.visitFieldInsn(opcode, owner, name, descriptor);
161     super.visitFieldInsn(opcode, owner, name, descriptor);
162   }
163 
164   @Override
165   @SuppressWarnings("deprecation")
visitMethodInsn( final int opcode, final String owner, final String name, final String descriptor, final boolean isInterface)166   public void visitMethodInsn(
167       final int opcode,
168       final String owner,
169       final String name,
170       final String descriptor,
171       final boolean isInterface) {
172     // Call the method that p is supposed to implement, depending on its api version.
173     if (p.api < Opcodes.ASM5) {
174       if (isInterface != (opcode == Opcodes.INVOKEINTERFACE)) {
175         throw new IllegalArgumentException("INVOKESPECIAL/STATIC on interfaces require ASM5");
176       }
177       // If p is an ASMifier (resp. Textifier), or a subclass that does not override the old
178       // visitMethodInsn method, the default implementation in Printer will redirect this to the
179       // new method in ASMifier (resp. Textifier). In all other cases, p overrides the old method
180       // and this call executes it.
181       p.visitMethodInsn(opcode, owner, name, descriptor);
182     } else {
183       p.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
184     }
185     if (mv != null) {
186       mv.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
187     }
188   }
189 
190   @Override
visitInvokeDynamicInsn( final String name, final String descriptor, final Handle bootstrapMethodHandle, final Object... bootstrapMethodArguments)191   public void visitInvokeDynamicInsn(
192       final String name,
193       final String descriptor,
194       final Handle bootstrapMethodHandle,
195       final Object... bootstrapMethodArguments) {
196     p.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
197     super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
198   }
199 
200   @Override
visitJumpInsn(final int opcode, final Label label)201   public void visitJumpInsn(final int opcode, final Label label) {
202     p.visitJumpInsn(opcode, label);
203     super.visitJumpInsn(opcode, label);
204   }
205 
206   @Override
visitLabel(final Label label)207   public void visitLabel(final Label label) {
208     p.visitLabel(label);
209     super.visitLabel(label);
210   }
211 
212   @Override
visitLdcInsn(final Object value)213   public void visitLdcInsn(final Object value) {
214     p.visitLdcInsn(value);
215     super.visitLdcInsn(value);
216   }
217 
218   @Override
visitIincInsn(final int varIndex, final int increment)219   public void visitIincInsn(final int varIndex, final int increment) {
220     p.visitIincInsn(varIndex, increment);
221     super.visitIincInsn(varIndex, increment);
222   }
223 
224   @Override
visitTableSwitchInsn( final int min, final int max, final Label dflt, final Label... labels)225   public void visitTableSwitchInsn(
226       final int min, final int max, final Label dflt, final Label... labels) {
227     p.visitTableSwitchInsn(min, max, dflt, labels);
228     super.visitTableSwitchInsn(min, max, dflt, labels);
229   }
230 
231   @Override
visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels)232   public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
233     p.visitLookupSwitchInsn(dflt, keys, labels);
234     super.visitLookupSwitchInsn(dflt, keys, labels);
235   }
236 
237   @Override
visitMultiANewArrayInsn(final String descriptor, final int numDimensions)238   public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
239     p.visitMultiANewArrayInsn(descriptor, numDimensions);
240     super.visitMultiANewArrayInsn(descriptor, numDimensions);
241   }
242 
243   @Override
visitInsnAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible)244   public AnnotationVisitor visitInsnAnnotation(
245       final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
246     Printer annotationPrinter = p.visitInsnAnnotation(typeRef, typePath, descriptor, visible);
247     return new TraceAnnotationVisitor(
248         super.visitInsnAnnotation(typeRef, typePath, descriptor, visible), annotationPrinter);
249   }
250 
251   @Override
visitTryCatchBlock( final Label start, final Label end, final Label handler, final String type)252   public void visitTryCatchBlock(
253       final Label start, final Label end, final Label handler, final String type) {
254     p.visitTryCatchBlock(start, end, handler, type);
255     super.visitTryCatchBlock(start, end, handler, type);
256   }
257 
258   @Override
visitTryCatchAnnotation( final int typeRef, final TypePath typePath, final String descriptor, final boolean visible)259   public AnnotationVisitor visitTryCatchAnnotation(
260       final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
261     Printer annotationPrinter = p.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible);
262     return new TraceAnnotationVisitor(
263         super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible), annotationPrinter);
264   }
265 
266   @Override
visitLocalVariable( final String name, final String descriptor, final String signature, final Label start, final Label end, final int index)267   public void visitLocalVariable(
268       final String name,
269       final String descriptor,
270       final String signature,
271       final Label start,
272       final Label end,
273       final int index) {
274     p.visitLocalVariable(name, descriptor, signature, start, end, index);
275     super.visitLocalVariable(name, descriptor, signature, start, end, index);
276   }
277 
278   @Override
visitLocalVariableAnnotation( final int typeRef, final TypePath typePath, final Label[] start, final Label[] end, final int[] index, final String descriptor, final boolean visible)279   public AnnotationVisitor visitLocalVariableAnnotation(
280       final int typeRef,
281       final TypePath typePath,
282       final Label[] start,
283       final Label[] end,
284       final int[] index,
285       final String descriptor,
286       final boolean visible) {
287     Printer annotationPrinter =
288         p.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible);
289     return new TraceAnnotationVisitor(
290         super.visitLocalVariableAnnotation(
291             typeRef, typePath, start, end, index, descriptor, visible),
292         annotationPrinter);
293   }
294 
295   @Override
visitLineNumber(final int line, final Label start)296   public void visitLineNumber(final int line, final Label start) {
297     p.visitLineNumber(line, start);
298     super.visitLineNumber(line, start);
299   }
300 
301   @Override
visitMaxs(final int maxStack, final int maxLocals)302   public void visitMaxs(final int maxStack, final int maxLocals) {
303     p.visitMaxs(maxStack, maxLocals);
304     super.visitMaxs(maxStack, maxLocals);
305   }
306 
307   @Override
visitEnd()308   public void visitEnd() {
309     p.visitMethodEnd();
310     super.visitEnd();
311   }
312 }
313