001    /***
002     * ASM: a very small and fast Java bytecode manipulation framework
003     * Copyright (c) 2000-2005 INRIA, France Telecom
004     * All rights reserved.
005     *
006     * Redistribution and use in source and binary forms, with or without
007     * modification, are permitted provided that the following conditions
008     * are met:
009     * 1. Redistributions of source code must retain the above copyright
010     *    notice, this list of conditions and the following disclaimer.
011     * 2. Redistributions in binary form must reproduce the above copyright
012     *    notice, this list of conditions and the following disclaimer in the
013     *    documentation and/or other materials provided with the distribution.
014     * 3. Neither the name of the copyright holders nor the names of its
015     *    contributors may be used to endorse or promote products derived from
016     *    this software without specific prior written permission.
017     *
018     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
028     * THE POSSIBILITY OF SUCH DAMAGE.
029     */
030    package net.sourceforge.retroweaver.optimizer;
031    
032    import org.objectweb.asm.AnnotationVisitor;
033    import org.objectweb.asm.Label;
034    import org.objectweb.asm.MethodAdapter;
035    import org.objectweb.asm.MethodVisitor;
036    import org.objectweb.asm.Opcodes;
037    
038    /**
039     * An {@link MethodVisitor} that collects the {@link Constant}s of the methods
040     * it visits.
041     * 
042     * @author Eric Bruneton
043     */
044    public class MethodConstantsCollector extends MethodAdapter {
045    
046        private ConstantPool cp;
047    
048        public MethodConstantsCollector(
049            final MethodVisitor mv,
050            final ConstantPool cp)
051        {
052            super(mv);
053            this.cp = cp;
054        }
055    
056        public AnnotationVisitor visitAnnotationDefault() {
057            cp.newUTF8("AnnotationDefault");
058            return new AnnotationConstantsCollector(mv.visitAnnotationDefault(), cp);
059        }
060    
061        public AnnotationVisitor visitAnnotation(
062            final String desc,
063            final boolean visible)
064        {
065            cp.newUTF8(desc);
066            if (visible) {
067                cp.newUTF8("RuntimeVisibleAnnotations");
068            } else {
069                cp.newUTF8("RuntimeInvisibleAnnotations");
070            }
071            return new AnnotationConstantsCollector(mv.visitAnnotation(desc,
072                    visible), cp);
073        }
074    
075        public AnnotationVisitor visitParameterAnnotation(
076            final int parameter,
077            final String desc,
078            final boolean visible)
079        {
080            cp.newUTF8(desc);
081            if (visible) {
082                cp.newUTF8("RuntimeVisibleParameterAnnotations");
083            } else {
084                cp.newUTF8("RuntimeInvisibleParameterAnnotations");
085            }
086            return new AnnotationConstantsCollector(mv.visitParameterAnnotation(parameter,
087                    desc,
088                    visible),
089                    cp);
090        }
091    
092        public void visitTypeInsn(final int opcode, final String desc) {
093            cp.newClass(desc);
094            mv.visitTypeInsn(opcode, desc);
095        }
096    
097        public void visitFieldInsn(
098            final int opcode,
099            final String owner,
100            final String name,
101            final String desc)
102        {
103            cp.newField(owner, name, desc);
104            mv.visitFieldInsn(opcode, owner, name, desc);
105        }
106    
107        public void visitMethodInsn(
108            final int opcode,
109            final String owner,
110            final String name,
111            final String desc)
112        {
113            boolean itf = opcode == Opcodes.INVOKEINTERFACE;
114            cp.newMethod(owner, name, desc, itf);
115            mv.visitMethodInsn(opcode, owner, name, desc);
116        }
117    
118        public void visitLdcInsn(final Object cst) {
119            cp.newConst(cst);
120            mv.visitLdcInsn(cst);
121        }
122    
123        public void visitMultiANewArrayInsn(final String desc, final int dims) {
124            cp.newClass(desc);
125            mv.visitMultiANewArrayInsn(desc, dims);
126        }
127    
128        public void visitTryCatchBlock(
129            final Label start,
130            final Label end,
131            final Label handler,
132            final String type)
133        {
134            if (type != null) {
135                cp.newClass(type);
136            }
137            mv.visitTryCatchBlock(start, end, handler, type);
138        }
139    
140        public void visitLocalVariable(
141            final String name,
142            final String desc,
143            final String signature,
144            final Label start,
145            final Label end,
146            final int index)
147        {
148            if (signature != null) {
149                cp.newUTF8("LocalVariableTypeTable");
150                cp.newUTF8(name);
151                cp.newUTF8(signature);
152            }
153            cp.newUTF8("LocalVariableTable");
154            cp.newUTF8(name);
155            cp.newUTF8(desc);
156            mv.visitLocalVariable(name, desc, signature, start, end, index);
157        }
158    
159        public void visitLineNumber(final int line, final Label start) {
160            cp.newUTF8("LineNumberTable");
161            mv.visitLineNumber(line, start);
162        }
163    
164        public void visitMaxs(final int maxStack, final int maxLocals) {
165            cp.newUTF8("Code");
166            mv.visitMaxs(maxStack, maxLocals);
167        }
168    }