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 29 package org.objectweb.asm.commons; 30 31 import java.util.ArrayList; 32 import org.objectweb.asm.Opcodes; 33 import org.objectweb.asm.signature.SignatureVisitor; 34 35 /** 36 * A {@link SignatureVisitor} that remaps types with a {@link Remapper}. 37 * 38 * @author Eugene Kuleshov 39 */ 40 public class SignatureRemapper extends SignatureVisitor { 41 42 private final SignatureVisitor signatureVisitor; 43 44 private final Remapper remapper; 45 46 private ArrayList<String> classNames = new ArrayList<>(); 47 48 /** 49 * Constructs a new {@link SignatureRemapper}. <i>Subclasses must not use this constructor</i>. 50 * Instead, they must use the {@link #SignatureRemapper(int,SignatureVisitor,Remapper)} version. 51 * 52 * @param signatureVisitor the signature visitor this remapper must delegate to. 53 * @param remapper the remapper to use to remap the types in the visited signature. 54 */ SignatureRemapper(final SignatureVisitor signatureVisitor, final Remapper remapper)55 public SignatureRemapper(final SignatureVisitor signatureVisitor, final Remapper remapper) { 56 this(/* latest api = */ Opcodes.ASM9, signatureVisitor, remapper); 57 } 58 59 /** 60 * Constructs a new {@link SignatureRemapper}. 61 * 62 * @param api the ASM API version supported by this remapper. Must be one of the {@code 63 * ASM}<i>x</i> values in {@link Opcodes}. 64 * @param signatureVisitor the signature visitor this remapper must delegate to. 65 * @param remapper the remapper to use to remap the types in the visited signature. 66 */ SignatureRemapper( final int api, final SignatureVisitor signatureVisitor, final Remapper remapper)67 protected SignatureRemapper( 68 final int api, final SignatureVisitor signatureVisitor, final Remapper remapper) { 69 super(api); 70 this.signatureVisitor = signatureVisitor; 71 this.remapper = remapper; 72 } 73 74 @Override visitClassType(final String name)75 public void visitClassType(final String name) { 76 classNames.add(name); 77 signatureVisitor.visitClassType(remapper.mapType(name)); 78 } 79 80 @Override visitInnerClassType(final String name)81 public void visitInnerClassType(final String name) { 82 String outerClassName = classNames.remove(classNames.size() - 1); 83 String className = outerClassName + '$' + name; 84 classNames.add(className); 85 String remappedOuter = remapper.mapType(outerClassName) + '$'; 86 String remappedName = remapper.mapType(className); 87 int index = 88 remappedName.startsWith(remappedOuter) 89 ? remappedOuter.length() 90 : remappedName.lastIndexOf('$') + 1; 91 signatureVisitor.visitInnerClassType(remappedName.substring(index)); 92 } 93 94 @Override visitFormalTypeParameter(final String name)95 public void visitFormalTypeParameter(final String name) { 96 signatureVisitor.visitFormalTypeParameter(name); 97 } 98 99 @Override visitTypeVariable(final String name)100 public void visitTypeVariable(final String name) { 101 signatureVisitor.visitTypeVariable(name); 102 } 103 104 @Override visitArrayType()105 public SignatureVisitor visitArrayType() { 106 signatureVisitor.visitArrayType(); 107 return this; 108 } 109 110 @Override visitBaseType(final char descriptor)111 public void visitBaseType(final char descriptor) { 112 signatureVisitor.visitBaseType(descriptor); 113 } 114 115 @Override visitClassBound()116 public SignatureVisitor visitClassBound() { 117 signatureVisitor.visitClassBound(); 118 return this; 119 } 120 121 @Override visitExceptionType()122 public SignatureVisitor visitExceptionType() { 123 signatureVisitor.visitExceptionType(); 124 return this; 125 } 126 127 @Override visitInterface()128 public SignatureVisitor visitInterface() { 129 signatureVisitor.visitInterface(); 130 return this; 131 } 132 133 @Override visitInterfaceBound()134 public SignatureVisitor visitInterfaceBound() { 135 signatureVisitor.visitInterfaceBound(); 136 return this; 137 } 138 139 @Override visitParameterType()140 public SignatureVisitor visitParameterType() { 141 signatureVisitor.visitParameterType(); 142 return this; 143 } 144 145 @Override visitReturnType()146 public SignatureVisitor visitReturnType() { 147 signatureVisitor.visitReturnType(); 148 return this; 149 } 150 151 @Override visitSuperclass()152 public SignatureVisitor visitSuperclass() { 153 signatureVisitor.visitSuperclass(); 154 return this; 155 } 156 157 @Override visitTypeArgument()158 public void visitTypeArgument() { 159 signatureVisitor.visitTypeArgument(); 160 } 161 162 @Override visitTypeArgument(final char wildcard)163 public SignatureVisitor visitTypeArgument(final char wildcard) { 164 signatureVisitor.visitTypeArgument(wildcard); 165 return this; 166 } 167 168 @Override visitEnd()169 public void visitEnd() { 170 signatureVisitor.visitEnd(); 171 classNames.remove(classNames.size() - 1); 172 } 173 } 174