• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000-2005 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  *    contributors may be used to endorse or promote products derived from
16  *    this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 package org.objectweb.asm.optimizer;
31 
32 import org.objectweb.asm.AnnotationVisitor;
33 import org.objectweb.asm.Attribute;
34 import org.objectweb.asm.ClassAdapter;
35 import org.objectweb.asm.ClassVisitor;
36 import org.objectweb.asm.FieldVisitor;
37 import org.objectweb.asm.MethodVisitor;
38 import org.objectweb.asm.Opcodes;
39 
40 /**
41  * A {@link ClassAdapter} that renames fields and methods, and removes debug
42  * info.
43  *
44  * @author Eric Bruneton
45  */
46 public class ClassOptimizer extends ClassAdapter {
47 
48     private NameMapping mapping;
49 
50     private String className;
51 
52     private String pkgName;
53 
ClassOptimizer(final ClassVisitor cv, final NameMapping mapping)54     public ClassOptimizer(final ClassVisitor cv, final NameMapping mapping) {
55         super(cv);
56         this.mapping = mapping;
57     }
58 
getClassName()59     public String getClassName() {
60         return className;
61     }
62 
63     // ------------------------------------------------------------------------
64     // Overriden methods
65     // ------------------------------------------------------------------------
66 
visit( final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces)67     public void visit(
68         final int version,
69         final int access,
70         final String name,
71         final String signature,
72         final String superName,
73         final String[] interfaces)
74     {
75         className = name;
76         pkgName = name.substring(0, name.lastIndexOf('/'));
77         cv.visit(version,
78                 access,
79                 mapping.map(name),
80                 null,
81                 mapping.map(superName),
82                 interfaces);
83     }
84 
visitSource(final String source, final String debug)85     public void visitSource(final String source, final String debug) {
86         // remove debug info
87     }
88 
visitOuterClass( final String owner, final String name, final String desc)89     public void visitOuterClass(
90         final String owner,
91         final String name,
92         final String desc)
93     {
94         // remove debug info
95     }
96 
visitAnnotation( final String desc, final boolean visible)97     public AnnotationVisitor visitAnnotation(
98         final String desc,
99         final boolean visible)
100     {
101         throw new UnsupportedOperationException();
102     }
103 
visitAttribute(final Attribute attr)104     public void visitAttribute(final Attribute attr) {
105         // remove non standard attribute
106     }
107 
visitInnerClass( final String name, final String outerName, final String innerName, final int access)108     public void visitInnerClass(
109         final String name,
110         final String outerName,
111         final String innerName,
112         final int access)
113     {
114         // remove debug info
115     }
116 
visitField( final int access, final String name, final String desc, final String signature, final Object value)117     public FieldVisitor visitField(
118         final int access,
119         final String name,
120         final String desc,
121         final String signature,
122         final Object value)
123     {
124         String s = className + "." + name;
125         if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) {
126             if ((access & Opcodes.ACC_FINAL) != 0
127                     && (access & Opcodes.ACC_STATIC) != 0 && desc.equals("I"))
128             {
129                 return null;
130             }
131             if (pkgName.equals("org/objectweb/asm")
132                     && mapping.map(s).equals(name))
133             {
134                 System.out.println("INFO: " + s + " could be renamed");
135             }
136             cv.visitField(access,
137                     mapping.map(s),
138                     mapping.fix(desc),
139                     null,
140                     value);
141         } else {
142             if (!mapping.map(s).equals(name)) {
143                 throw new RuntimeException("The public or protected field " + s
144                         + " must not be renamed.");
145             }
146             cv.visitField(access, name, desc, null, value);
147         }
148         return null; // remove debug info
149     }
150 
visitMethod( final int access, final String name, final String desc, final String signature, final String[] exceptions)151     public MethodVisitor visitMethod(
152         final int access,
153         final String name,
154         final String desc,
155         final String signature,
156         final String[] exceptions)
157     {
158         String s = className + "." + name + desc;
159         if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) {
160             if (pkgName.equals("org/objectweb/asm") && !name.startsWith("<")
161                     && mapping.map(s).equals(name))
162             {
163                 System.out.println("INFO: " + s + " could be renamed");
164             }
165             return new MethodOptimizer(cv.visitMethod(access,
166                     mapping.map(s),
167                     mapping.fix(desc),
168                     null,
169                     exceptions), mapping);
170         } else {
171             if (!mapping.map(s).equals(name)) {
172                 throw new RuntimeException("The public or protected method "
173                         + s + " must not be renamed.");
174             }
175             return new MethodOptimizer(cv.visitMethod(access,
176                     name,
177                     desc,
178                     null,
179                     exceptions), mapping);
180         }
181     }
182 }
183