001: /***
002: * ASM: a very small and fast Java bytecode manipulation framework
003: * Copyright (c) 2000-2007 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: */package org.objectweb.asm.commons;
030:
031: import org.objectweb.asm.Type;
032: import org.objectweb.asm.signature.SignatureReader;
033: import org.objectweb.asm.signature.SignatureVisitor;
034: import org.objectweb.asm.signature.SignatureWriter;
035:
036: /**
037: * A class responsible for remapping types and names.
038: * Subclasses can override the following methods:
039: *
040: * <ul>
041: * <li>{@link #map(String)} - map type</li>
042: * <li>{@link #mapFieldName(String, String, String)} - map field name</li>
043: * <li>{@link #mapMethodName(String, String, String)} - map method name</li>
044: * </ul>
045: *
046: * @author Eugene Kuleshov
047: */
048: public abstract class Remapper {
049:
050: public String mapDesc(String desc) {
051: Type t = Type.getType(desc);
052: switch (t.getSort()) {
053: case Type.ARRAY:
054: String s = mapDesc(t.getElementType().getDescriptor());
055: for (int i = 0; i < t.getDimensions(); ++i) {
056: s = '[' + s;
057: }
058: return s;
059: case Type.OBJECT:
060: String newType = map(t.getInternalName());
061: if (newType != null) {
062: return 'L' + newType + ';';
063: }
064: }
065: return desc;
066: }
067:
068: private Type mapType(Type t) {
069: switch (t.getSort()) {
070: case Type.ARRAY:
071: String s = mapDesc(t.getElementType().getDescriptor());
072: for (int i = 0; i < t.getDimensions(); ++i) {
073: s = '[' + s;
074: }
075: return Type.getType(s);
076: case Type.OBJECT:
077: s = map(t.getInternalName());
078: if (s != null) {
079: return Type.getObjectType(s);
080: }
081: }
082: return t;
083: }
084:
085: public String mapType(String type) {
086: if (type == null) {
087: return null;
088: }
089: return mapType(Type.getObjectType(type)).getInternalName();
090: }
091:
092: public String[] mapTypes(String[] types) {
093: String[] newTypes = null;
094: boolean needMapping = false;
095: for (int i = 0; i < types.length; i++) {
096: String type = types[i];
097: String newType = map(type);
098: if (newType != null && newTypes == null) {
099: newTypes = new String[types.length];
100: if (i > 0) {
101: System.arraycopy(types, 0, newTypes, 0, i);
102: }
103: needMapping = true;
104: }
105: if (needMapping) {
106: newTypes[i] = newType == null ? type : newType;
107: }
108: }
109: return needMapping ? newTypes : types;
110: }
111:
112: public String mapMethodDesc(String desc) {
113: if ("()V".equals(desc)) {
114: return desc;
115: }
116:
117: Type[] args = Type.getArgumentTypes(desc);
118: String s = "(";
119: for (int i = 0; i < args.length; i++) {
120: s += mapDesc(args[i].getDescriptor());
121: }
122: Type returnType = Type.getReturnType(desc);
123: if (returnType == Type.VOID_TYPE) {
124: return s + ")V";
125: }
126: return s + ')' + mapDesc(returnType.getDescriptor());
127: }
128:
129: public Object mapValue(Object value) {
130: return value instanceof Type ? mapType((Type) value) : value;
131: }
132:
133: /**
134: *
135: * @param typeSignature true if signature is a FieldTypeSignature, such as
136: * the signature parameter of the ClassVisitor.visitField or
137: * MethodVisitor.visitLocalVariable methods
138: */
139: public String mapSignature(String signature, boolean typeSignature) {
140: if (signature == null) {
141: return null;
142: }
143: SignatureReader r = new SignatureReader(signature);
144: SignatureWriter w = new SignatureWriter();
145: SignatureVisitor a = createRemappingSignatureAdapter(w);
146: if (typeSignature) {
147: r.acceptType(a);
148: } else {
149: r.accept(a);
150: }
151: return w.toString();
152: }
153:
154: protected SignatureVisitor createRemappingSignatureAdapter(
155: SignatureVisitor v) {
156: return new RemappingSignatureAdapter(v, this );
157: }
158:
159: /**
160: * Map method name to the new name. Subclasses can override.
161: */
162: public String mapMethodName(String owner, String name, String desc) {
163: return name;
164: }
165:
166: /**
167: * Map field name to the new name. Subclasses can override.
168: */
169: public String mapFieldName(String owner, String name, String desc) {
170: return name;
171: }
172:
173: /**
174: * Map type name to the new name. Subclasses can override.
175: */
176: public String map(String typeName) {
177: return typeName;
178: }
179:
180: }
|