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 54 public ClassOptimizer(final ClassVisitor cv, final NameMapping mapping) { 55 super(cv); 56 this.mapping = mapping; 57 } 58 59 public String getClassName() { 60 return className; 61 } 62 63 // ------------------------------------------------------------------------ 64 // Overriden methods 65 // ------------------------------------------------------------------------ 66 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 85 public void visitSource(final String source, final String debug) { 86 // remove debug info 87 } 88 89 public void visitOuterClass( 90 final String owner, 91 final String name, 92 final String desc) 93 { 94 // remove debug info 95 } 96 97 public AnnotationVisitor visitAnnotation( 98 final String desc, 99 final boolean visible) 100 { 101 throw new UnsupportedOperationException(); 102 } 103 104 public void visitAttribute(final Attribute attr) { 105 // remove non standard attribute 106 } 107 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 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 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