Blame contrib/asm/src/org/objectweb/asm/commons/Remapper.java

Packit 5e46da
/***
Packit 5e46da
 * ASM: a very small and fast Java bytecode manipulation framework
Packit 5e46da
 * Copyright (c) 2000-2011 INRIA, France Telecom
Packit 5e46da
 * All rights reserved.
Packit 5e46da
 *
Packit 5e46da
 * Redistribution and use in source and binary forms, with or without
Packit 5e46da
 * modification, are permitted provided that the following conditions
Packit 5e46da
 * are met:
Packit 5e46da
 * 1. Redistributions of source code must retain the above copyright
Packit 5e46da
 *    notice, this list of conditions and the following disclaimer.
Packit 5e46da
 * 2. Redistributions in binary form must reproduce the above copyright
Packit 5e46da
 *    notice, this list of conditions and the following disclaimer in the
Packit 5e46da
 *    documentation and/or other materials provided with the distribution.
Packit 5e46da
 * 3. Neither the name of the copyright holders nor the names of its
Packit 5e46da
 *    contributors may be used to endorse or promote products derived from
Packit 5e46da
 *    this software without specific prior written permission.
Packit 5e46da
 *
Packit 5e46da
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 5e46da
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 5e46da
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 5e46da
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
Packit 5e46da
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Packit 5e46da
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
Packit 5e46da
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
Packit 5e46da
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
Packit 5e46da
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
Packit 5e46da
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
Packit 5e46da
 * THE POSSIBILITY OF SUCH DAMAGE.
Packit 5e46da
 */
Packit 5e46da
Packit 5e46da
package org.objectweb.asm.commons;
Packit 5e46da
Packit 5e46da
import org.objectweb.asm.Handle;
Packit 5e46da
import org.objectweb.asm.Type;
Packit 5e46da
import org.objectweb.asm.signature.SignatureReader;
Packit 5e46da
import org.objectweb.asm.signature.SignatureVisitor;
Packit 5e46da
import org.objectweb.asm.signature.SignatureWriter;
Packit 5e46da
Packit 5e46da
/**
Packit 5e46da
 * A class responsible for remapping types and names. Subclasses can override
Packit 5e46da
 * the following methods:
Packit 5e46da
 * 
Packit 5e46da
 * 
    Packit 5e46da
     * 
  • {@link #map(String)} - map type
  • Packit 5e46da
     * 
  • {@link #mapFieldName(String, String, String)} - map field name
  • Packit 5e46da
     * 
  • {@link #mapMethodName(String, String, String)} - map method name
  • Packit 5e46da
     * 
    Packit 5e46da
     * 
    Packit 5e46da
     * @author Eugene Kuleshov
    Packit 5e46da
     */
    Packit 5e46da
    public abstract class Remapper {
    Packit 5e46da
    Packit 5e46da
        public String mapDesc(String desc) {
    Packit 5e46da
            Type t = Type.getType(desc);
    Packit 5e46da
            switch (t.getSort()) {
    Packit 5e46da
            case Type.ARRAY:
    Packit 5e46da
                String s = mapDesc(t.getElementType().getDescriptor());
    Packit 5e46da
                for (int i = 0; i < t.getDimensions(); ++i) {
    Packit 5e46da
                    s = '[' + s;
    Packit 5e46da
                }
    Packit 5e46da
                return s;
    Packit 5e46da
            case Type.OBJECT:
    Packit 5e46da
                String newType = map(t.getInternalName());
    Packit 5e46da
                if (newType != null) {
    Packit 5e46da
                    return 'L' + newType + ';';
    Packit 5e46da
                }
    Packit 5e46da
            }
    Packit 5e46da
            return desc;
    Packit 5e46da
        }
    Packit 5e46da
    Packit 5e46da
        private Type mapType(Type t) {
    Packit 5e46da
            switch (t.getSort()) {
    Packit 5e46da
            case Type.ARRAY:
    Packit 5e46da
                String s = mapDesc(t.getElementType().getDescriptor());
    Packit 5e46da
                for (int i = 0; i < t.getDimensions(); ++i) {
    Packit 5e46da
                    s = '[' + s;
    Packit 5e46da
                }
    Packit 5e46da
                return Type.getType(s);
    Packit 5e46da
            case Type.OBJECT:
    Packit 5e46da
                s = map(t.getInternalName());
    Packit 5e46da
                return s != null ? Type.getObjectType(s) : t;
    Packit 5e46da
            case Type.METHOD:
    Packit 5e46da
                return Type.getMethodType(mapMethodDesc(t.getDescriptor()));
    Packit 5e46da
            }
    Packit 5e46da
            return t;
    Packit 5e46da
        }
    Packit 5e46da
    Packit 5e46da
        public String mapType(String type) {
    Packit 5e46da
            if (type == null) {
    Packit 5e46da
                return null;
    Packit 5e46da
            }
    Packit 5e46da
            return mapType(Type.getObjectType(type)).getInternalName();
    Packit 5e46da
        }
    Packit 5e46da
    Packit 5e46da
        public String[] mapTypes(String[] types) {
    Packit 5e46da
            String[] newTypes = null;
    Packit 5e46da
            boolean needMapping = false;
    Packit 5e46da
            for (int i = 0; i < types.length; i++) {
    Packit 5e46da
                String type = types[i];
    Packit 5e46da
                String newType = map(type);
    Packit 5e46da
                if (newType != null && newTypes == null) {
    Packit 5e46da
                    newTypes = new String[types.length];
    Packit 5e46da
                    if (i > 0) {
    Packit 5e46da
                        System.arraycopy(types, 0, newTypes, 0, i);
    Packit 5e46da
                    }
    Packit 5e46da
                    needMapping = true;
    Packit 5e46da
                }
    Packit 5e46da
                if (needMapping) {
    Packit 5e46da
                    newTypes[i] = newType == null ? type : newType;
    Packit 5e46da
                }
    Packit 5e46da
            }
    Packit 5e46da
            return needMapping ? newTypes : types;
    Packit 5e46da
        }
    Packit 5e46da
    Packit 5e46da
        public String mapMethodDesc(String desc) {
    Packit 5e46da
            if ("()V".equals(desc)) {
    Packit 5e46da
                return desc;
    Packit 5e46da
            }
    Packit 5e46da
    Packit 5e46da
            Type[] args = Type.getArgumentTypes(desc);
    Packit 5e46da
            StringBuilder sb = new StringBuilder("(");
    Packit 5e46da
            for (int i = 0; i < args.length; i++) {
    Packit 5e46da
                sb.append(mapDesc(args[i].getDescriptor()));
    Packit 5e46da
            }
    Packit 5e46da
            Type returnType = Type.getReturnType(desc);
    Packit 5e46da
            if (returnType == Type.VOID_TYPE) {
    Packit 5e46da
                sb.append(")V");
    Packit 5e46da
                return sb.toString();
    Packit 5e46da
            }
    Packit 5e46da
            sb.append(')').append(mapDesc(returnType.getDescriptor()));
    Packit 5e46da
            return sb.toString();
    Packit 5e46da
        }
    Packit 5e46da
    Packit 5e46da
        public Object mapValue(Object value) {
    Packit 5e46da
            if (value instanceof Type) {
    Packit 5e46da
                return mapType((Type) value);
    Packit 5e46da
            }
    Packit 5e46da
            if (value instanceof Handle) {
    Packit 5e46da
                Handle h = (Handle) value;
    Packit 5e46da
                return new Handle(h.getTag(), mapType(h.getOwner()), mapMethodName(
    Packit 5e46da
                        h.getOwner(), h.getName(), h.getDesc()),
    Packit 5e46da
                        mapMethodDesc(h.getDesc()));
    Packit 5e46da
            }
    Packit 5e46da
            return value;
    Packit 5e46da
        }
    Packit 5e46da
    Packit 5e46da
        /**
    Packit 5e46da
         * 
    Packit 5e46da
         * @param typeSignature
    Packit 5e46da
         *            true if signature is a FieldTypeSignature, such as the
    Packit 5e46da
         *            signature parameter of the ClassVisitor.visitField or
    Packit 5e46da
         *            MethodVisitor.visitLocalVariable methods
    Packit 5e46da
         */
    Packit 5e46da
        public String mapSignature(String signature, boolean typeSignature) {
    Packit 5e46da
            if (signature == null) {
    Packit 5e46da
                return null;
    Packit 5e46da
            }
    Packit 5e46da
            SignatureReader r = new SignatureReader(signature);
    Packit 5e46da
            SignatureWriter w = new SignatureWriter();
    Packit 5e46da
            SignatureVisitor a = createRemappingSignatureAdapter(w);
    Packit 5e46da
            if (typeSignature) {
    Packit 5e46da
                r.acceptType(a);
    Packit 5e46da
            } else {
    Packit 5e46da
                r.accept(a);
    Packit 5e46da
            }
    Packit 5e46da
            return w.toString();
    Packit 5e46da
        }
    Packit 5e46da
    Packit 5e46da
        protected SignatureVisitor createRemappingSignatureAdapter(
    Packit 5e46da
                SignatureVisitor v) {
    Packit 5e46da
            return new RemappingSignatureAdapter(v, this);
    Packit 5e46da
        }
    Packit 5e46da
    Packit 5e46da
        /**
    Packit 5e46da
         * Map method name to the new name. Subclasses can override.
    Packit 5e46da
         * 
    Packit 5e46da
         * @param owner
    Packit 5e46da
         *            owner of the method.
    Packit 5e46da
         * @param name
    Packit 5e46da
         *            name of the method.
    Packit 5e46da
         * @param desc
    Packit 5e46da
         *            descriptor of the method.
    Packit 5e46da
         * @return new name of the method
    Packit 5e46da
         */
    Packit 5e46da
        public String mapMethodName(String owner, String name, String desc) {
    Packit 5e46da
            return name;
    Packit 5e46da
        }
    Packit 5e46da
    Packit 5e46da
        /**
    Packit 5e46da
         * Map invokedynamic method name to the new name. Subclasses can override.
    Packit 5e46da
         * 
    Packit 5e46da
         * @param name
    Packit 5e46da
         *            name of the invokedynamic.
    Packit 5e46da
         * @param desc
    Packit 5e46da
         *            descriptor of the invokedynamic.
    Packit 5e46da
         * @return new invokdynamic name.
    Packit 5e46da
         */
    Packit 5e46da
        public String mapInvokeDynamicMethodName(String name, String desc) {
    Packit 5e46da
            return name;
    Packit 5e46da
        }
    Packit 5e46da
    Packit 5e46da
        /**
    Packit 5e46da
         * Map field name to the new name. Subclasses can override.
    Packit 5e46da
         * 
    Packit 5e46da
         * @param owner
    Packit 5e46da
         *            owner of the field.
    Packit 5e46da
         * @param name
    Packit 5e46da
         *            name of the field
    Packit 5e46da
         * @param desc
    Packit 5e46da
         *            descriptor of the field
    Packit 5e46da
         * @return new name of the field.
    Packit 5e46da
         */
    Packit 5e46da
        public String mapFieldName(String owner, String name, String desc) {
    Packit 5e46da
            return name;
    Packit 5e46da
        }
    Packit 5e46da
    Packit 5e46da
        /**
    Packit 5e46da
         * Map type name to the new name. Subclasses can override.
    Packit 5e46da
         */
    Packit 5e46da
        public String map(String typeName) {
    Packit 5e46da
            return typeName;
    Packit 5e46da
        }
    Packit 5e46da
    }