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.Attribute;
034    import org.objectweb.asm.ClassAdapter;
035    import org.objectweb.asm.ClassVisitor;
036    import org.objectweb.asm.FieldVisitor;
037    import org.objectweb.asm.MethodVisitor;
038    import org.objectweb.asm.Opcodes;
039    
040    /**
041     * A {@link ClassVisitor} that collects the {@link Constant}s of the classes it
042     * visits.
043     * 
044     * @author Eric Bruneton
045     */
046    public class ClassConstantsCollector extends ClassAdapter {
047    
048        private ConstantPool cp;
049    
050        public ClassConstantsCollector(final ClassVisitor cv, final ConstantPool cp)
051        {
052            super(cv);
053            this.cp = cp;
054        }
055    
056        public void visit(
057            final int version,
058            final int access,
059            final String name,
060            final String signature,
061            final String superName,
062            final String[] interfaces)
063        {
064            if ((access & Opcodes.ACC_DEPRECATED) != 0) {
065                cp.newUTF8("Deprecated");
066            }
067            if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
068                cp.newUTF8("Synthetic");
069            }
070            cp.newClass(name);
071            if (signature != null) {
072                cp.newUTF8("Signature");
073                cp.newUTF8(signature);
074            }
075            if (superName != null) {
076                cp.newClass(superName);
077            }
078            if (interfaces != null) {
079                for (int i = 0; i < interfaces.length; ++i) {
080                    cp.newClass(interfaces[i]);
081                }
082            }
083            cv.visit(version, access, name, signature, superName, interfaces);
084        }
085    
086        public void visitSource(final String source, final String debug) {
087            if (source != null) {
088                cp.newUTF8("SourceFile");
089                cp.newUTF8(source);
090            }
091            if (debug != null) {
092                cp.newUTF8("SourceDebugExtension");
093            }
094            cv.visitSource(source, debug);
095        }
096    
097        public void visitOuterClass(
098            final String owner,
099            final String name,
100            final String desc)
101        {
102            cp.newUTF8("EnclosingMethod");
103            cp.newClass(owner);
104            if (name != null && desc != null) {
105                cp.newNameType(name, desc);
106            }
107            cv.visitOuterClass(owner, name, desc);
108        }
109    
110        public AnnotationVisitor visitAnnotation(
111            final String desc,
112            final boolean visible)
113        {
114            cp.newUTF8(desc);
115            if (visible) {
116                cp.newUTF8("RuntimeVisibleAnnotations");
117            } else {
118                cp.newUTF8("RuntimeInvisibleAnnotations");
119            }
120            return new AnnotationConstantsCollector(cv.visitAnnotation(desc,
121                    visible), cp);
122        }
123    
124        public void visitAttribute(final Attribute attr) {
125            cv.visitAttribute(attr);
126        }
127    
128        public void visitInnerClass(
129            final String name,
130            final String outerName,
131            final String innerName,
132            final int access)
133        {
134            cp.newUTF8("InnerClasses");
135            if (name != null) {
136                cp.newClass(name);
137            }
138            if (outerName != null) {
139                cp.newClass(outerName);
140            }
141            if (innerName != null) {
142                cp.newUTF8(innerName);
143            }
144            cv.visitInnerClass(name, outerName, innerName, access);
145        }
146    
147        public FieldVisitor visitField(
148            final int access,
149            final String name,
150            final String desc,
151            final String signature,
152            final Object value)
153        {
154            if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
155                cp.newUTF8("Synthetic");
156            }
157            if ((access & Opcodes.ACC_DEPRECATED) != 0) {
158                cp.newUTF8("Deprecated");
159            }
160            cp.newUTF8(name);
161            cp.newUTF8(desc);
162            if (signature != null) {
163                cp.newUTF8("Signature");
164                cp.newUTF8(signature);
165            }
166            if (value != null) {
167                cp.newConst(value);
168            }
169            return new FieldConstantsCollector(cv.visitField(access,
170                    name,
171                    desc,
172                    signature,
173                    value), cp);
174        }
175    
176        public MethodVisitor visitMethod(
177            final int access,
178            final String name,
179            final String desc,
180            final String signature,
181            final String[] exceptions)
182        {
183            if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
184                cp.newUTF8("Synthetic");
185            }
186            if ((access & Opcodes.ACC_DEPRECATED) != 0) {
187                cp.newUTF8("Deprecated");
188            }
189            cp.newUTF8(name);
190            cp.newUTF8(desc);
191            if (signature != null) {
192                cp.newUTF8("Signature");
193                cp.newUTF8(signature);
194            }
195            if (exceptions != null) {
196                cp.newUTF8("Exceptions");
197                for (int i = 0; i < exceptions.length; ++i) {
198                    cp.newClass(exceptions[i]);
199                }
200            }
201            return new MethodConstantsCollector(cv.visitMethod(access,
202                    name,
203                    desc,
204                    signature,
205                    exceptions), cp);
206        }
207    
208        public void visitEnd() {
209            cv.visitEnd();
210        }
211    }