diff --git a/contrib/asm/src/org/objectweb/asm/commons/LocalVariablesSorter.java b/contrib/asm/src/org/objectweb/asm/commons/LocalVariablesSorter.java
new file mode 100644
index 00000000..295c319b
--- /dev/null
+++ b/contrib/asm/src/org/objectweb/asm/commons/LocalVariablesSorter.java
@@ -0,0 +1,381 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link MethodVisitor} that renumbers local variables in their order of
+ * appearance. This adapter allows one to easily add new local variables to a
+ * method. It may be used by inheriting from this class, but the preferred way
+ * of using it is via delegation: the next visitor in the chain can indeed add
+ * new locals when needed by calling {@link #newLocal} on this adapter (this
+ * requires a reference back to this {@link LocalVariablesSorter}).
+ *
+ * @author Chris Nokleberg
+ * @author Eugene Kuleshov
+ * @author Eric Bruneton
+ */
+public class LocalVariablesSorter extends MethodVisitor {
+
+ private static final Type OBJECT_TYPE = Type
+ .getObjectType("java/lang/Object");
+
+ /**
+ * Mapping from old to new local variable indexes. A local variable at index
+ * i of size 1 is remapped to 'mapping[2*i]', while a local variable at
+ * index i of size 2 is remapped to 'mapping[2*i+1]'.
+ */
+ private int[] mapping = new int[40];
+
+ /**
+ * Array used to store stack map local variable types after remapping.
+ */
+ private Object[] newLocals = new Object[20];
+
+ /**
+ * Index of the first local variable, after formal parameters.
+ */
+ protected final int firstLocal;
+
+ /**
+ * Index of the next local variable to be created by {@link #newLocal}.
+ */
+ protected int nextLocal;
+
+ /**
+ * Indicates if at least one local variable has moved due to remapping.
+ */
+ private boolean changed;
+
+ /**
+ * Creates a new {@link LocalVariablesSorter}. Subclasses must not use
+ * this constructor. Instead, they must use the
+ * {@link #LocalVariablesSorter(int, int, String, MethodVisitor)} version.
+ *
+ * @param access
+ * access flags of the adapted method.
+ * @param desc
+ * the method's descriptor (see {@link Type Type}).
+ * @param mv
+ * the method visitor to which this adapter delegates calls.
+ * @throws IllegalStateException
+ * If a subclass calls this constructor.
+ */
+ public LocalVariablesSorter(final int access, final String desc,
+ final MethodVisitor mv) {
+ this(Opcodes.ASM5, access, desc, mv);
+ if (getClass() != LocalVariablesSorter.class) {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * Creates a new {@link LocalVariablesSorter}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ * @param access
+ * access flags of the adapted method.
+ * @param desc
+ * the method's descriptor (see {@link Type Type}).
+ * @param mv
+ * the method visitor to which this adapter delegates calls.
+ */
+ protected LocalVariablesSorter(final int api, final int access,
+ final String desc, final MethodVisitor mv) {
+ super(api, mv);
+ Type[] args = Type.getArgumentTypes(desc);
+ nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0;
+ for (int i = 0; i < args.length; i++) {
+ nextLocal += args[i].getSize();
+ }
+ firstLocal = nextLocal;
+ }
+
+ @Override
+ public void visitVarInsn(final int opcode, final int var) {
+ Type type;
+ switch (opcode) {
+ case Opcodes.LLOAD:
+ case Opcodes.LSTORE:
+ type = Type.LONG_TYPE;
+ break;
+
+ case Opcodes.DLOAD:
+ case Opcodes.DSTORE:
+ type = Type.DOUBLE_TYPE;
+ break;
+
+ case Opcodes.FLOAD:
+ case Opcodes.FSTORE:
+ type = Type.FLOAT_TYPE;
+ break;
+
+ case Opcodes.ILOAD:
+ case Opcodes.ISTORE:
+ type = Type.INT_TYPE;
+ break;
+
+ default:
+ // case Opcodes.ALOAD:
+ // case Opcodes.ASTORE:
+ // case RET:
+ type = OBJECT_TYPE;
+ break;
+ }
+ mv.visitVarInsn(opcode, remap(var, type));
+ }
+
+ @Override
+ public void visitIincInsn(final int var, final int increment) {
+ mv.visitIincInsn(remap(var, Type.INT_TYPE), increment);
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ mv.visitMaxs(maxStack, nextLocal);
+ }
+
+ @Override
+ public void visitLocalVariable(final String name, final String desc,
+ final String signature, final Label start, final Label end,
+ final int index) {
+ int newIndex = remap(index, Type.getType(desc));
+ mv.visitLocalVariable(name, desc, signature, start, end, newIndex);
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+ TypePath typePath, Label[] start, Label[] end, int[] index,
+ String desc, boolean visible) {
+ Type t = Type.getType(desc);
+ int[] newIndex = new int[index.length];
+ for (int i = 0; i < newIndex.length; ++i) {
+ newIndex[i] = remap(index[i], t);
+ }
+ return mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
+ newIndex, desc, visible);
+ }
+
+ @Override
+ public void visitFrame(final int type, final int nLocal,
+ final Object[] local, final int nStack, final Object[] stack) {
+ if (type != Opcodes.F_NEW) { // uncompressed frame
+ throw new IllegalStateException(
+ "ClassReader.accept() should be called with EXPAND_FRAMES flag");
+ }
+
+ if (!changed) { // optimization for the case where mapping = identity
+ mv.visitFrame(type, nLocal, local, nStack, stack);
+ return;
+ }
+
+ // creates a copy of newLocals
+ Object[] oldLocals = new Object[newLocals.length];
+ System.arraycopy(newLocals, 0, oldLocals, 0, oldLocals.length);
+
+ updateNewLocals(newLocals);
+
+ // copies types from 'local' to 'newLocals'
+ // 'newLocals' already contains the variables added with 'newLocal'
+
+ int index = 0; // old local variable index
+ int number = 0; // old local variable number
+ for (; number < nLocal; ++number) {
+ Object t = local[number];
+ int size = t == Opcodes.LONG || t == Opcodes.DOUBLE ? 2 : 1;
+ if (t != Opcodes.TOP) {
+ Type typ = OBJECT_TYPE;
+ if (t == Opcodes.INTEGER) {
+ typ = Type.INT_TYPE;
+ } else if (t == Opcodes.FLOAT) {
+ typ = Type.FLOAT_TYPE;
+ } else if (t == Opcodes.LONG) {
+ typ = Type.LONG_TYPE;
+ } else if (t == Opcodes.DOUBLE) {
+ typ = Type.DOUBLE_TYPE;
+ } else if (t instanceof String) {
+ typ = Type.getObjectType((String) t);
+ }
+ setFrameLocal(remap(index, typ), t);
+ }
+ index += size;
+ }
+
+ // removes TOP after long and double types as well as trailing TOPs
+
+ index = 0;
+ number = 0;
+ for (int i = 0; index < newLocals.length; ++i) {
+ Object t = newLocals[index++];
+ if (t != null && t != Opcodes.TOP) {
+ newLocals[i] = t;
+ number = i + 1;
+ if (t == Opcodes.LONG || t == Opcodes.DOUBLE) {
+ index += 1;
+ }
+ } else {
+ newLocals[i] = Opcodes.TOP;
+ }
+ }
+
+ // visits remapped frame
+ mv.visitFrame(type, number, newLocals, nStack, stack);
+
+ // restores original value of 'newLocals'
+ newLocals = oldLocals;
+ }
+
+ // -------------
+
+ /**
+ * Creates a new local variable of the given type.
+ *
+ * @param type
+ * the type of the local variable to be created.
+ * @return the identifier of the newly created local variable.
+ */
+ public int newLocal(final Type type) {
+ Object t;
+ switch (type.getSort()) {
+ case Type.BOOLEAN:
+ case Type.CHAR:
+ case Type.BYTE:
+ case Type.SHORT:
+ case Type.INT:
+ t = Opcodes.INTEGER;
+ break;
+ case Type.FLOAT:
+ t = Opcodes.FLOAT;
+ break;
+ case Type.LONG:
+ t = Opcodes.LONG;
+ break;
+ case Type.DOUBLE:
+ t = Opcodes.DOUBLE;
+ break;
+ case Type.ARRAY:
+ t = type.getDescriptor();
+ break;
+ // case Type.OBJECT:
+ default:
+ t = type.getInternalName();
+ break;
+ }
+ int local = newLocalMapping(type);
+ setLocalType(local, type);
+ setFrameLocal(local, t);
+ changed = true;
+ return local;
+ }
+
+ /**
+ * Notifies subclasses that a new stack map frame is being visited. The
+ * array argument contains the stack map frame types corresponding to the
+ * local variables added with {@link #newLocal}. This method can update
+ * these types in place for the stack map frame being visited. The default
+ * implementation of this method does nothing, i.e. a local variable added
+ * with {@link #newLocal} will have the same type in all stack map frames.
+ * But this behavior is not always the desired one, for instance if a local
+ * variable is added in the middle of a try/catch block: the frame for the
+ * exception handler should have a TOP type for this new local.
+ *
+ * @param newLocals
+ * the stack map frame types corresponding to the local variables
+ * added with {@link #newLocal} (and null for the others). The
+ * format of this array is the same as in
+ * {@link MethodVisitor#visitFrame}, except that long and double
+ * types use two slots. The types for the current stack map frame
+ * must be updated in place in this array.
+ */
+ protected void updateNewLocals(Object[] newLocals) {
+ }
+
+ /**
+ * Notifies subclasses that a local variable has been added or remapped. The
+ * default implementation of this method does nothing.
+ *
+ * @param local
+ * a local variable identifier, as returned by {@link #newLocal
+ * newLocal()}.
+ * @param type
+ * the type of the value being stored in the local variable.
+ */
+ protected void setLocalType(final int local, final Type type) {
+ }
+
+ private void setFrameLocal(final int local, final Object type) {
+ int l = newLocals.length;
+ if (local >= l) {
+ Object[] a = new Object[Math.max(2 * l, local + 1)];
+ System.arraycopy(newLocals, 0, a, 0, l);
+ newLocals = a;
+ }
+ newLocals[local] = type;
+ }
+
+ private int remap(final int var, final Type type) {
+ if (var + type.getSize() <= firstLocal) {
+ return var;
+ }
+ int key = 2 * var + type.getSize() - 1;
+ int size = mapping.length;
+ if (key >= size) {
+ int[] newMapping = new int[Math.max(2 * size, key + 1)];
+ System.arraycopy(mapping, 0, newMapping, 0, size);
+ mapping = newMapping;
+ }
+ int value = mapping[key];
+ if (value == 0) {
+ value = newLocalMapping(type);
+ setLocalType(value, type);
+ mapping[key] = value + 1;
+ } else {
+ value--;
+ }
+ if (value != var) {
+ changed = true;
+ }
+ return value;
+ }
+
+ protected int newLocalMapping(final Type type) {
+ int local = nextLocal;
+ nextLocal += type.getSize();
+ return local;
+ }
+}
diff --git a/contrib/asm/src/org/objectweb/asm/commons/Remapper.java b/contrib/asm/src/org/objectweb/asm/commons/Remapper.java
new file mode 100644
index 00000000..121cf887
--- /dev/null
+++ b/contrib/asm/src/org/objectweb/asm/commons/Remapper.java
@@ -0,0 +1,223 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.signature.SignatureReader;
+import org.objectweb.asm.signature.SignatureVisitor;
+import org.objectweb.asm.signature.SignatureWriter;
+
+/**
+ * A class responsible for remapping types and names. Subclasses can override
+ * the following methods:
+ *
+ *
+ * - {@link #map(String)} - map type
+ * - {@link #mapFieldName(String, String, String)} - map field name
+ * - {@link #mapMethodName(String, String, String)} - map method name
+ *
+ *
+ * @author Eugene Kuleshov
+ */
+public abstract class Remapper {
+
+ public String mapDesc(String desc) {
+ Type t = Type.getType(desc);
+ switch (t.getSort()) {
+ case Type.ARRAY:
+ String s = mapDesc(t.getElementType().getDescriptor());
+ for (int i = 0; i < t.getDimensions(); ++i) {
+ s = '[' + s;
+ }
+ return s;
+ case Type.OBJECT:
+ String newType = map(t.getInternalName());
+ if (newType != null) {
+ return 'L' + newType + ';';
+ }
+ }
+ return desc;
+ }
+
+ private Type mapType(Type t) {
+ switch (t.getSort()) {
+ case Type.ARRAY:
+ String s = mapDesc(t.getElementType().getDescriptor());
+ for (int i = 0; i < t.getDimensions(); ++i) {
+ s = '[' + s;
+ }
+ return Type.getType(s);
+ case Type.OBJECT:
+ s = map(t.getInternalName());
+ return s != null ? Type.getObjectType(s) : t;
+ case Type.METHOD:
+ return Type.getMethodType(mapMethodDesc(t.getDescriptor()));
+ }
+ return t;
+ }
+
+ public String mapType(String type) {
+ if (type == null) {
+ return null;
+ }
+ return mapType(Type.getObjectType(type)).getInternalName();
+ }
+
+ public String[] mapTypes(String[] types) {
+ String[] newTypes = null;
+ boolean needMapping = false;
+ for (int i = 0; i < types.length; i++) {
+ String type = types[i];
+ String newType = map(type);
+ if (newType != null && newTypes == null) {
+ newTypes = new String[types.length];
+ if (i > 0) {
+ System.arraycopy(types, 0, newTypes, 0, i);
+ }
+ needMapping = true;
+ }
+ if (needMapping) {
+ newTypes[i] = newType == null ? type : newType;
+ }
+ }
+ return needMapping ? newTypes : types;
+ }
+
+ public String mapMethodDesc(String desc) {
+ if ("()V".equals(desc)) {
+ return desc;
+ }
+
+ Type[] args = Type.getArgumentTypes(desc);
+ StringBuilder sb = new StringBuilder("(");
+ for (int i = 0; i < args.length; i++) {
+ sb.append(mapDesc(args[i].getDescriptor()));
+ }
+ Type returnType = Type.getReturnType(desc);
+ if (returnType == Type.VOID_TYPE) {
+ sb.append(")V");
+ return sb.toString();
+ }
+ sb.append(')').append(mapDesc(returnType.getDescriptor()));
+ return sb.toString();
+ }
+
+ public Object mapValue(Object value) {
+ if (value instanceof Type) {
+ return mapType((Type) value);
+ }
+ if (value instanceof Handle) {
+ Handle h = (Handle) value;
+ return new Handle(h.getTag(), mapType(h.getOwner()), mapMethodName(
+ h.getOwner(), h.getName(), h.getDesc()),
+ mapMethodDesc(h.getDesc()));
+ }
+ return value;
+ }
+
+ /**
+ *
+ * @param typeSignature
+ * true if signature is a FieldTypeSignature, such as the
+ * signature parameter of the ClassVisitor.visitField or
+ * MethodVisitor.visitLocalVariable methods
+ */
+ public String mapSignature(String signature, boolean typeSignature) {
+ if (signature == null) {
+ return null;
+ }
+ SignatureReader r = new SignatureReader(signature);
+ SignatureWriter w = new SignatureWriter();
+ SignatureVisitor a = createRemappingSignatureAdapter(w);
+ if (typeSignature) {
+ r.acceptType(a);
+ } else {
+ r.accept(a);
+ }
+ return w.toString();
+ }
+
+ protected SignatureVisitor createRemappingSignatureAdapter(
+ SignatureVisitor v) {
+ return new RemappingSignatureAdapter(v, this);
+ }
+
+ /**
+ * Map method name to the new name. Subclasses can override.
+ *
+ * @param owner
+ * owner of the method.
+ * @param name
+ * name of the method.
+ * @param desc
+ * descriptor of the method.
+ * @return new name of the method
+ */
+ public String mapMethodName(String owner, String name, String desc) {
+ return name;
+ }
+
+ /**
+ * Map invokedynamic method name to the new name. Subclasses can override.
+ *
+ * @param name
+ * name of the invokedynamic.
+ * @param desc
+ * descriptor of the invokedynamic.
+ * @return new invokdynamic name.
+ */
+ public String mapInvokeDynamicMethodName(String name, String desc) {
+ return name;
+ }
+
+ /**
+ * Map field name to the new name. Subclasses can override.
+ *
+ * @param owner
+ * owner of the field.
+ * @param name
+ * name of the field
+ * @param desc
+ * descriptor of the field
+ * @return new name of the field.
+ */
+ public String mapFieldName(String owner, String name, String desc) {
+ return name;
+ }
+
+ /**
+ * Map type name to the new name. Subclasses can override.
+ */
+ public String map(String typeName) {
+ return typeName;
+ }
+}
diff --git a/contrib/asm/src/org/objectweb/asm/commons/RemappingAnnotationAdapter.java b/contrib/asm/src/org/objectweb/asm/commons/RemappingAnnotationAdapter.java
new file mode 100644
index 00000000..b9749fcf
--- /dev/null
+++ b/contrib/asm/src/org/objectweb/asm/commons/RemappingAnnotationAdapter.java
@@ -0,0 +1,79 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * An {@link AnnotationVisitor} adapter for type remapping.
+ *
+ * @author Eugene Kuleshov
+ */
+public class RemappingAnnotationAdapter extends AnnotationVisitor {
+
+ protected final Remapper remapper;
+
+ public RemappingAnnotationAdapter(final AnnotationVisitor av,
+ final Remapper remapper) {
+ this(Opcodes.ASM5, av, remapper);
+ }
+
+ protected RemappingAnnotationAdapter(final int api,
+ final AnnotationVisitor av, final Remapper remapper) {
+ super(api, av);
+ this.remapper = remapper;
+ }
+
+ @Override
+ public void visit(String name, Object value) {
+ av.visit(name, remapper.mapValue(value));
+ }
+
+ @Override
+ public void visitEnum(String name, String desc, String value) {
+ av.visitEnum(name, remapper.mapDesc(desc), value);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(String name, String desc) {
+ AnnotationVisitor v = av.visitAnnotation(name, remapper.mapDesc(desc));
+ return v == null ? null : (v == av ? this
+ : new RemappingAnnotationAdapter(v, remapper));
+ }
+
+ @Override
+ public AnnotationVisitor visitArray(String name) {
+ AnnotationVisitor v = av.visitArray(name);
+ return v == null ? null : (v == av ? this
+ : new RemappingAnnotationAdapter(v, remapper));
+ }
+}
diff --git a/contrib/asm/src/org/objectweb/asm/commons/RemappingClassAdapter.java b/contrib/asm/src/org/objectweb/asm/commons/RemappingClassAdapter.java
new file mode 100644
index 00000000..c0b52cae
--- /dev/null
+++ b/contrib/asm/src/org/objectweb/asm/commons/RemappingClassAdapter.java
@@ -0,0 +1,135 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link ClassVisitor} for type remapping.
+ *
+ * @author Eugene Kuleshov
+ */
+public class RemappingClassAdapter extends ClassVisitor {
+
+ protected final Remapper remapper;
+
+ protected String className;
+
+ public RemappingClassAdapter(final ClassVisitor cv, final Remapper remapper) {
+ this(Opcodes.ASM5, cv, remapper);
+ }
+
+ protected RemappingClassAdapter(final int api, final ClassVisitor cv,
+ final Remapper remapper) {
+ super(api, cv);
+ this.remapper = remapper;
+ }
+
+ @Override
+ public void visit(int version, int access, String name, String signature,
+ String superName, String[] interfaces) {
+ this.className = name;
+ super.visit(version, access, remapper.mapType(name), remapper
+ .mapSignature(signature, false), remapper.mapType(superName),
+ interfaces == null ? null : remapper.mapTypes(interfaces));
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
+ visible);
+ return av == null ? null : createRemappingAnnotationAdapter(av);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
+ remapper.mapDesc(desc), visible);
+ return av == null ? null : createRemappingAnnotationAdapter(av);
+ }
+
+ @Override
+ public FieldVisitor visitField(int access, String name, String desc,
+ String signature, Object value) {
+ FieldVisitor fv = super.visitField(access,
+ remapper.mapFieldName(className, name, desc),
+ remapper.mapDesc(desc), remapper.mapSignature(signature, true),
+ remapper.mapValue(value));
+ return fv == null ? null : createRemappingFieldAdapter(fv);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String desc,
+ String signature, String[] exceptions) {
+ String newDesc = remapper.mapMethodDesc(desc);
+ MethodVisitor mv = super.visitMethod(access, remapper.mapMethodName(
+ className, name, desc), newDesc, remapper.mapSignature(
+ signature, false),
+ exceptions == null ? null : remapper.mapTypes(exceptions));
+ return mv == null ? null : createRemappingMethodAdapter(access,
+ newDesc, mv);
+ }
+
+ @Override
+ public void visitInnerClass(String name, String outerName,
+ String innerName, int access) {
+ // TODO should innerName be changed?
+ super.visitInnerClass(remapper.mapType(name), outerName == null ? null
+ : remapper.mapType(outerName), innerName, access);
+ }
+
+ @Override
+ public void visitOuterClass(String owner, String name, String desc) {
+ super.visitOuterClass(remapper.mapType(owner), name == null ? null
+ : remapper.mapMethodName(owner, name, desc),
+ desc == null ? null : remapper.mapMethodDesc(desc));
+ }
+
+ protected FieldVisitor createRemappingFieldAdapter(FieldVisitor fv) {
+ return new RemappingFieldAdapter(fv, remapper);
+ }
+
+ protected MethodVisitor createRemappingMethodAdapter(int access,
+ String newDesc, MethodVisitor mv) {
+ return new RemappingMethodAdapter(access, newDesc, mv, remapper);
+ }
+
+ protected AnnotationVisitor createRemappingAnnotationAdapter(
+ AnnotationVisitor av) {
+ return new RemappingAnnotationAdapter(av, remapper);
+ }
+}
diff --git a/contrib/asm/src/org/objectweb/asm/commons/RemappingFieldAdapter.java b/contrib/asm/src/org/objectweb/asm/commons/RemappingFieldAdapter.java
new file mode 100644
index 00000000..3179abac
--- /dev/null
+++ b/contrib/asm/src/org/objectweb/asm/commons/RemappingFieldAdapter.java
@@ -0,0 +1,71 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link FieldVisitor} adapter for type remapping.
+ *
+ * @author Eugene Kuleshov
+ */
+public class RemappingFieldAdapter extends FieldVisitor {
+
+ private final Remapper remapper;
+
+ public RemappingFieldAdapter(final FieldVisitor fv, final Remapper remapper) {
+ this(Opcodes.ASM5, fv, remapper);
+ }
+
+ protected RemappingFieldAdapter(final int api, final FieldVisitor fv,
+ final Remapper remapper) {
+ super(api, fv);
+ this.remapper = remapper;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ AnnotationVisitor av = fv.visitAnnotation(remapper.mapDesc(desc),
+ visible);
+ return av == null ? null : new RemappingAnnotationAdapter(av, remapper);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
+ remapper.mapDesc(desc), visible);
+ return av == null ? null : new RemappingAnnotationAdapter(av, remapper);
+ }
+}
diff --git a/contrib/asm/src/org/objectweb/asm/commons/RemappingMethodAdapter.java b/contrib/asm/src/org/objectweb/asm/commons/RemappingMethodAdapter.java
new file mode 100644
index 00000000..c9badc2a
--- /dev/null
+++ b/contrib/asm/src/org/objectweb/asm/commons/RemappingMethodAdapter.java
@@ -0,0 +1,224 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.TypePath;
+
+/**
+ * A {@link LocalVariablesSorter} for type mapping.
+ *
+ * @author Eugene Kuleshov
+ */
+public class RemappingMethodAdapter extends LocalVariablesSorter {
+
+ protected final Remapper remapper;
+
+ public RemappingMethodAdapter(final int access, final String desc,
+ final MethodVisitor mv, final Remapper remapper) {
+ this(Opcodes.ASM5, access, desc, mv, remapper);
+ }
+
+ protected RemappingMethodAdapter(final int api, final int access,
+ final String desc, final MethodVisitor mv, final Remapper remapper) {
+ super(api, access, desc, mv);
+ this.remapper = remapper;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ AnnotationVisitor av = super.visitAnnotationDefault();
+ return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
+ visible);
+ return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ AnnotationVisitor av = super.visitTypeAnnotation(typeRef, typePath,
+ remapper.mapDesc(desc), visible);
+ return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(int parameter,
+ String desc, boolean visible) {
+ AnnotationVisitor av = super.visitParameterAnnotation(parameter,
+ remapper.mapDesc(desc), visible);
+ return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+ }
+
+ @Override
+ public void visitFrame(int type, int nLocal, Object[] local, int nStack,
+ Object[] stack) {
+ super.visitFrame(type, nLocal, remapEntries(nLocal, local), nStack,
+ remapEntries(nStack, stack));
+ }
+
+ private Object[] remapEntries(int n, Object[] entries) {
+ for (int i = 0; i < n; i++) {
+ if (entries[i] instanceof String) {
+ Object[] newEntries = new Object[n];
+ if (i > 0) {
+ System.arraycopy(entries, 0, newEntries, 0, i);
+ }
+ do {
+ Object t = entries[i];
+ newEntries[i++] = t instanceof String ? remapper
+ .mapType((String) t) : t;
+ } while (i < n);
+ return newEntries;
+ }
+ }
+ return entries;
+ }
+
+ @Override
+ public void visitFieldInsn(int opcode, String owner, String name,
+ String desc) {
+ super.visitFieldInsn(opcode, remapper.mapType(owner),
+ remapper.mapFieldName(owner, name, desc),
+ remapper.mapDesc(desc));
+ }
+
+ @Deprecated
+ @Override
+ public void visitMethodInsn(final int opcode, final String owner,
+ final String name, final String desc) {
+ if (api >= Opcodes.ASM5) {
+ super.visitMethodInsn(opcode, owner, name, desc);
+ return;
+ }
+ doVisitMethodInsn(opcode, owner, name, desc,
+ opcode == Opcodes.INVOKEINTERFACE);
+ }
+
+ @Override
+ public void visitMethodInsn(final int opcode, final String owner,
+ final String name, final String desc, final boolean itf) {
+ if (api < Opcodes.ASM5) {
+ super.visitMethodInsn(opcode, owner, name, desc, itf);
+ return;
+ }
+ doVisitMethodInsn(opcode, owner, name, desc, itf);
+ }
+
+ private void doVisitMethodInsn(int opcode, String owner, String name,
+ String desc, boolean itf) {
+ // Calling super.visitMethodInsn requires to call the correct version
+ // depending on this.api (otherwise infinite loops can occur). To
+ // simplify and to make it easier to automatically remove the backward
+ // compatibility code, we inline the code of the overridden method here.
+ // IMPORTANT: THIS ASSUMES THAT visitMethodInsn IS NOT OVERRIDDEN IN
+ // LocalVariableSorter.
+ if (mv != null) {
+ mv.visitMethodInsn(opcode, remapper.mapType(owner),
+ remapper.mapMethodName(owner, name, desc),
+ remapper.mapMethodDesc(desc), itf);
+ }
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+ Object... bsmArgs) {
+ for (int i = 0; i < bsmArgs.length; i++) {
+ bsmArgs[i] = remapper.mapValue(bsmArgs[i]);
+ }
+ super.visitInvokeDynamicInsn(
+ remapper.mapInvokeDynamicMethodName(name, desc),
+ remapper.mapMethodDesc(desc), (Handle) remapper.mapValue(bsm),
+ bsmArgs);
+ }
+
+ @Override
+ public void visitTypeInsn(int opcode, String type) {
+ super.visitTypeInsn(opcode, remapper.mapType(type));
+ }
+
+ @Override
+ public void visitLdcInsn(Object cst) {
+ super.visitLdcInsn(remapper.mapValue(cst));
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(String desc, int dims) {
+ super.visitMultiANewArrayInsn(remapper.mapDesc(desc), dims);
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ AnnotationVisitor av = super.visitInsnAnnotation(typeRef, typePath,
+ remapper.mapDesc(desc), visible);
+ return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+ }
+
+ @Override
+ public void visitTryCatchBlock(Label start, Label end, Label handler,
+ String type) {
+ super.visitTryCatchBlock(start, end, handler, type == null ? null
+ : remapper.mapType(type));
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ AnnotationVisitor av = super.visitTryCatchAnnotation(typeRef, typePath,
+ remapper.mapDesc(desc), visible);
+ return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+ }
+
+ @Override
+ public void visitLocalVariable(String name, String desc, String signature,
+ Label start, Label end, int index) {
+ super.visitLocalVariable(name, remapper.mapDesc(desc),
+ remapper.mapSignature(signature, true), start, end, index);
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+ TypePath typePath, Label[] start, Label[] end, int[] index,
+ String desc, boolean visible) {
+ AnnotationVisitor av = super.visitLocalVariableAnnotation(typeRef,
+ typePath, start, end, index, remapper.mapDesc(desc), visible);
+ return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
+ }
+}
diff --git a/contrib/asm/src/org/objectweb/asm/commons/RemappingSignatureAdapter.java b/contrib/asm/src/org/objectweb/asm/commons/RemappingSignatureAdapter.java
new file mode 100644
index 00000000..5728034c
--- /dev/null
+++ b/contrib/asm/src/org/objectweb/asm/commons/RemappingSignatureAdapter.java
@@ -0,0 +1,155 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.objectweb.asm.commons;
+
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.signature.SignatureVisitor;
+
+/**
+ * A {@link SignatureVisitor} adapter for type mapping.
+ *
+ * @author Eugene Kuleshov
+ */
+public class RemappingSignatureAdapter extends SignatureVisitor {
+
+ private final SignatureVisitor v;
+
+ private final Remapper remapper;
+
+ private String className;
+
+ public RemappingSignatureAdapter(final SignatureVisitor v,
+ final Remapper remapper) {
+ this(Opcodes.ASM5, v, remapper);
+ }
+
+ protected RemappingSignatureAdapter(final int api,
+ final SignatureVisitor v, final Remapper remapper) {
+ super(api);
+ this.v = v;
+ this.remapper = remapper;
+ }
+
+ @Override
+ public void visitClassType(String name) {
+ className = name;
+ v.visitClassType(remapper.mapType(name));
+ }
+
+ @Override
+ public void visitInnerClassType(String name) {
+ String remappedOuter = remapper.mapType(className) + '$';
+ className = className + '$' + name;
+ String remappedName = remapper.mapType(className);
+ int index = remappedName.startsWith(remappedOuter) ? remappedOuter
+ .length() : remappedName.lastIndexOf('$') + 1;
+ v.visitInnerClassType(remappedName.substring(index));
+ }
+
+ @Override
+ public void visitFormalTypeParameter(String name) {
+ v.visitFormalTypeParameter(name);
+ }
+
+ @Override
+ public void visitTypeVariable(String name) {
+ v.visitTypeVariable(name);
+ }
+
+ @Override
+ public SignatureVisitor visitArrayType() {
+ v.visitArrayType();
+ return this;
+ }
+
+ @Override
+ public void visitBaseType(char descriptor) {
+ v.visitBaseType(descriptor);
+ }
+
+ @Override
+ public SignatureVisitor visitClassBound() {
+ v.visitClassBound();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitExceptionType() {
+ v.visitExceptionType();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitInterface() {
+ v.visitInterface();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitInterfaceBound() {
+ v.visitInterfaceBound();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitParameterType() {
+ v.visitParameterType();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitReturnType() {
+ v.visitReturnType();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitSuperclass() {
+ v.visitSuperclass();
+ return this;
+ }
+
+ @Override
+ public void visitTypeArgument() {
+ v.visitTypeArgument();
+ }
+
+ @Override
+ public SignatureVisitor visitTypeArgument(char wildcard) {
+ v.visitTypeArgument(wildcard);
+ return this;
+ }
+
+ @Override
+ public void visitEnd() {
+ v.visitEnd();
+ }
+}
diff --git a/contrib/asm/src/org/objectweb/asm/commons/SimpleRemapper.java b/contrib/asm/src/org/objectweb/asm/commons/SimpleRemapper.java
new file mode 100644
index 00000000..7b42b9bc
--- /dev/null
+++ b/contrib/asm/src/org/objectweb/asm/commons/SimpleRemapper.java
@@ -0,0 +1,75 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.objectweb.asm.commons;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * A {@link Remapper} using a {@link Map} to define its mapping.
+ *
+ * @author Eugene Kuleshov
+ */
+public class SimpleRemapper extends Remapper {
+
+ private final Map mapping;
+
+ public SimpleRemapper(Map mapping) {
+ this.mapping = mapping;
+ }
+
+ public SimpleRemapper(String oldName, String newName) {
+ this.mapping = Collections.singletonMap(oldName, newName);
+ }
+
+ @Override
+ public String mapMethodName(String owner, String name, String desc) {
+ String s = map(owner + '.' + name + desc);
+ return s == null ? name : s;
+ }
+
+ @Override
+ public String mapInvokeDynamicMethodName(String name, String desc) {
+ String s = map('.' + name + desc);
+ return s == null ? name : s;
+ }
+
+ @Override
+ public String mapFieldName(String owner, String name, String desc) {
+ String s = map(owner + '.' + name);
+ return s == null ? name : s;
+ }
+
+ @Override
+ public String map(String key) {
+ return mapping.get(key);
+ }
+}
diff --git a/contrib/asm/src/org/objectweb/asm/signature/SignatureReader.java b/contrib/asm/src/org/objectweb/asm/signature/SignatureReader.java
new file mode 100644
index 00000000..1083b3de
--- /dev/null
+++ b/contrib/asm/src/org/objectweb/asm/signature/SignatureReader.java
@@ -0,0 +1,228 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.signature;
+
+/**
+ * A type signature parser to make a signature visitor visit an existing
+ * signature.
+ *
+ * @author Thomas Hallgren
+ * @author Eric Bruneton
+ */
+public class SignatureReader {
+
+ /**
+ * The signature to be read.
+ */
+ private final String signature;
+
+ /**
+ * Constructs a {@link SignatureReader} for the given signature.
+ *
+ * @param signature
+ * A ClassSignature, MethodTypeSignature, or
+ * FieldTypeSignature.
+ */
+ public SignatureReader(final String signature) {
+ this.signature = signature;
+ }
+
+ /**
+ * Makes the given visitor visit the signature of this
+ * {@link SignatureReader}. This signature is the one specified in the
+ * constructor (see {@link #SignatureReader(String) SignatureReader}). This
+ * method is intended to be called on a {@link SignatureReader} that was
+ * created using a ClassSignature (such as the signature
+ * parameter of the {@link org.objectweb.asm.ClassVisitor#visit
+ * ClassVisitor.visit} method) or a MethodTypeSignature (such as the
+ * signature
parameter of the
+ * {@link org.objectweb.asm.ClassVisitor#visitMethod
+ * ClassVisitor.visitMethod} method).
+ *
+ * @param v
+ * the visitor that must visit this signature.
+ */
+ public void accept(final SignatureVisitor v) {
+ String signature = this.signature;
+ int len = signature.length();
+ int pos;
+ char c;
+
+ if (signature.charAt(0) == '<') {
+ pos = 2;
+ do {
+ int end = signature.indexOf(':', pos);
+ v.visitFormalTypeParameter(signature.substring(pos - 1, end));
+ pos = end + 1;
+
+ c = signature.charAt(pos);
+ if (c == 'L' || c == '[' || c == 'T') {
+ pos = parseType(signature, pos, v.visitClassBound());
+ }
+
+ while ((c = signature.charAt(pos++)) == ':') {
+ pos = parseType(signature, pos, v.visitInterfaceBound());
+ }
+ } while (c != '>');
+ } else {
+ pos = 0;
+ }
+
+ if (signature.charAt(pos) == '(') {
+ pos++;
+ while (signature.charAt(pos) != ')') {
+ pos = parseType(signature, pos, v.visitParameterType());
+ }
+ pos = parseType(signature, pos + 1, v.visitReturnType());
+ while (pos < len) {
+ pos = parseType(signature, pos + 1, v.visitExceptionType());
+ }
+ } else {
+ pos = parseType(signature, pos, v.visitSuperclass());
+ while (pos < len) {
+ pos = parseType(signature, pos, v.visitInterface());
+ }
+ }
+ }
+
+ /**
+ * Makes the given visitor visit the signature of this
+ * {@link SignatureReader}. This signature is the one specified in the
+ * constructor (see {@link #SignatureReader(String) SignatureReader}). This
+ * method is intended to be called on a {@link SignatureReader} that was
+ * created using a FieldTypeSignature, such as the
+ * signature
parameter of the
+ * {@link org.objectweb.asm.ClassVisitor#visitField ClassVisitor.visitField}
+ * or {@link org.objectweb.asm.MethodVisitor#visitLocalVariable
+ * MethodVisitor.visitLocalVariable} methods.
+ *
+ * @param v
+ * the visitor that must visit this signature.
+ */
+ public void acceptType(final SignatureVisitor v) {
+ parseType(this.signature, 0, v);
+ }
+
+ /**
+ * Parses a field type signature and makes the given visitor visit it.
+ *
+ * @param signature
+ * a string containing the signature that must be parsed.
+ * @param pos
+ * index of the first character of the signature to parsed.
+ * @param v
+ * the visitor that must visit this signature.
+ * @return the index of the first character after the parsed signature.
+ */
+ private static int parseType(final String signature, int pos,
+ final SignatureVisitor v) {
+ char c;
+ int start, end;
+ boolean visited, inner;
+ String name;
+
+ switch (c = signature.charAt(pos++)) {
+ case 'Z':
+ case 'C':
+ case 'B':
+ case 'S':
+ case 'I':
+ case 'F':
+ case 'J':
+ case 'D':
+ case 'V':
+ v.visitBaseType(c);
+ return pos;
+
+ case '[':
+ return parseType(signature, pos, v.visitArrayType());
+
+ case 'T':
+ end = signature.indexOf(';', pos);
+ v.visitTypeVariable(signature.substring(pos, end));
+ return end + 1;
+
+ default: // case 'L':
+ start = pos;
+ visited = false;
+ inner = false;
+ for (;;) {
+ switch (c = signature.charAt(pos++)) {
+ case '.':
+ case ';':
+ if (!visited) {
+ name = signature.substring(start, pos - 1);
+ if (inner) {
+ v.visitInnerClassType(name);
+ } else {
+ v.visitClassType(name);
+ }
+ }
+ if (c == ';') {
+ v.visitEnd();
+ return pos;
+ }
+ start = pos;
+ visited = false;
+ inner = true;
+ break;
+
+ case '<':
+ name = signature.substring(start, pos - 1);
+ if (inner) {
+ v.visitInnerClassType(name);
+ } else {
+ v.visitClassType(name);
+ }
+ visited = true;
+ top: for (;;) {
+ switch (c = signature.charAt(pos)) {
+ case '>':
+ break top;
+ case '*':
+ ++pos;
+ v.visitTypeArgument();
+ break;
+ case '+':
+ case '-':
+ pos = parseType(signature, pos + 1,
+ v.visitTypeArgument(c));
+ break;
+ default:
+ pos = parseType(signature, pos,
+ v.visitTypeArgument('='));
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/contrib/asm/src/org/objectweb/asm/signature/SignatureVisitor.java b/contrib/asm/src/org/objectweb/asm/signature/SignatureVisitor.java
new file mode 100644
index 00000000..1dba32d5
--- /dev/null
+++ b/contrib/asm/src/org/objectweb/asm/signature/SignatureVisitor.java
@@ -0,0 +1,238 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.signature;
+
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A visitor to visit a generic signature. The methods of this interface must be
+ * called in one of the three following orders (the last one is the only valid
+ * order for a {@link SignatureVisitor} that is returned by a method of this
+ * interface):
+ *
+ * - ClassSignature = ( visitFormalTypeParameter
+ * visitClassBound? visitInterfaceBound* )* (
+ * visitSuperclass visitInterface* )
+ * - MethodSignature = ( visitFormalTypeParameter
+ * visitClassBound? visitInterfaceBound* )* (
+ * visitParameterType* visitReturnType
+ * visitExceptionType* )
+ * - TypeSignature = visitBaseType |
+ * visitTypeVariable | visitArrayType | (
+ * visitClassType visitTypeArgument* (
+ * visitInnerClassType visitTypeArgument* )* visitEnd
+ * ) )
+ *
+ *
+ * @author Thomas Hallgren
+ * @author Eric Bruneton
+ */
+public abstract class SignatureVisitor {
+
+ /**
+ * Wildcard for an "extends" type argument.
+ */
+ public final static char EXTENDS = '+';
+
+ /**
+ * Wildcard for a "super" type argument.
+ */
+ public final static char SUPER = '-';
+
+ /**
+ * Wildcard for a normal type argument.
+ */
+ public final static char INSTANCEOF = '=';
+
+ /**
+ * The ASM API version implemented by this visitor. The value of this field
+ * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ */
+ protected final int api;
+
+ /**
+ * Constructs a new {@link SignatureVisitor}.
+ *
+ * @param api
+ * the ASM API version implemented by this visitor. Must be one
+ * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+ */
+ public SignatureVisitor(final int api) {
+ if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+ throw new IllegalArgumentException();
+ }
+ this.api = api;
+ }
+
+ /**
+ * Visits a formal type parameter.
+ *
+ * @param name
+ * the name of the formal parameter.
+ */
+ public void visitFormalTypeParameter(String name) {
+ }
+
+ /**
+ * Visits the class bound of the last visited formal type parameter.
+ *
+ * @return a non null visitor to visit the signature of the class bound.
+ */
+ public SignatureVisitor visitClassBound() {
+ return this;
+ }
+
+ /**
+ * Visits an interface bound of the last visited formal type parameter.
+ *
+ * @return a non null visitor to visit the signature of the interface bound.
+ */
+ public SignatureVisitor visitInterfaceBound() {
+ return this;
+ }
+
+ /**
+ * Visits the type of the super class.
+ *
+ * @return a non null visitor to visit the signature of the super class
+ * type.
+ */
+ public SignatureVisitor visitSuperclass() {
+ return this;
+ }
+
+ /**
+ * Visits the type of an interface implemented by the class.
+ *
+ * @return a non null visitor to visit the signature of the interface type.
+ */
+ public SignatureVisitor visitInterface() {
+ return this;
+ }
+
+ /**
+ * Visits the type of a method parameter.
+ *
+ * @return a non null visitor to visit the signature of the parameter type.
+ */
+ public SignatureVisitor visitParameterType() {
+ return this;
+ }
+
+ /**
+ * Visits the return type of the method.
+ *
+ * @return a non null visitor to visit the signature of the return type.
+ */
+ public SignatureVisitor visitReturnType() {
+ return this;
+ }
+
+ /**
+ * Visits the type of a method exception.
+ *
+ * @return a non null visitor to visit the signature of the exception type.
+ */
+ public SignatureVisitor visitExceptionType() {
+ return this;
+ }
+
+ /**
+ * Visits a signature corresponding to a primitive type.
+ *
+ * @param descriptor
+ * the descriptor of the primitive type, or 'V' for void
+ * .
+ */
+ public void visitBaseType(char descriptor) {
+ }
+
+ /**
+ * Visits a signature corresponding to a type variable.
+ *
+ * @param name
+ * the name of the type variable.
+ */
+ public void visitTypeVariable(String name) {
+ }
+
+ /**
+ * Visits a signature corresponding to an array type.
+ *
+ * @return a non null visitor to visit the signature of the array element
+ * type.
+ */
+ public SignatureVisitor visitArrayType() {
+ return this;
+ }
+
+ /**
+ * Starts the visit of a signature corresponding to a class or interface
+ * type.
+ *
+ * @param name
+ * the internal name of the class or interface.
+ */
+ public void visitClassType(String name) {
+ }
+
+ /**
+ * Visits an inner class.
+ *
+ * @param name
+ * the local name of the inner class in its enclosing class.
+ */
+ public void visitInnerClassType(String name) {
+ }
+
+ /**
+ * Visits an unbounded type argument of the last visited class or inner
+ * class type.
+ */
+ public void visitTypeArgument() {
+ }
+
+ /**
+ * Visits a type argument of the last visited class or inner class type.
+ *
+ * @param wildcard
+ * '+', '-' or '='.
+ * @return a non null visitor to visit the signature of the type argument.
+ */
+ public SignatureVisitor visitTypeArgument(char wildcard) {
+ return this;
+ }
+
+ /**
+ * Ends the visit of a signature corresponding to a class or interface type.
+ */
+ public void visitEnd() {
+ }
+}
diff --git a/contrib/asm/src/org/objectweb/asm/signature/SignatureWriter.java b/contrib/asm/src/org/objectweb/asm/signature/SignatureWriter.java
new file mode 100644
index 00000000..ec475dbf
--- /dev/null
+++ b/contrib/asm/src/org/objectweb/asm/signature/SignatureWriter.java
@@ -0,0 +1,227 @@
+/***
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.objectweb.asm.signature;
+
+import org.objectweb.asm.Opcodes;
+
+/**
+ * A signature visitor that generates signatures in string format.
+ *
+ * @author Thomas Hallgren
+ * @author Eric Bruneton
+ */
+public class SignatureWriter extends SignatureVisitor {
+
+ /**
+ * Buffer used to construct the signature.
+ */
+ private final StringBuffer buf = new StringBuffer();
+
+ /**
+ * Indicates if the signature contains formal type parameters.
+ */
+ private boolean hasFormals;
+
+ /**
+ * Indicates if the signature contains method parameter types.
+ */
+ private boolean hasParameters;
+
+ /**
+ * Stack used to keep track of class types that have arguments. Each element
+ * of this stack is a boolean encoded in one bit. The top of the stack is
+ * the lowest order bit. Pushing false = *2, pushing true = *2+1, popping =
+ * /2.
+ */
+ private int argumentStack;
+
+ /**
+ * Constructs a new {@link SignatureWriter} object.
+ */
+ public SignatureWriter() {
+ super(Opcodes.ASM5);
+ }
+
+ // ------------------------------------------------------------------------
+ // Implementation of the SignatureVisitor interface
+ // ------------------------------------------------------------------------
+
+ @Override
+ public void visitFormalTypeParameter(final String name) {
+ if (!hasFormals) {
+ hasFormals = true;
+ buf.append('<');
+ }
+ buf.append(name);
+ buf.append(':');
+ }
+
+ @Override
+ public SignatureVisitor visitClassBound() {
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitInterfaceBound() {
+ buf.append(':');
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitSuperclass() {
+ endFormals();
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitInterface() {
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitParameterType() {
+ endFormals();
+ if (!hasParameters) {
+ hasParameters = true;
+ buf.append('(');
+ }
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitReturnType() {
+ endFormals();
+ if (!hasParameters) {
+ buf.append('(');
+ }
+ buf.append(')');
+ return this;
+ }
+
+ @Override
+ public SignatureVisitor visitExceptionType() {
+ buf.append('^');
+ return this;
+ }
+
+ @Override
+ public void visitBaseType(final char descriptor) {
+ buf.append(descriptor);
+ }
+
+ @Override
+ public void visitTypeVariable(final String name) {
+ buf.append('T');
+ buf.append(name);
+ buf.append(';');
+ }
+
+ @Override
+ public SignatureVisitor visitArrayType() {
+ buf.append('[');
+ return this;
+ }
+
+ @Override
+ public void visitClassType(final String name) {
+ buf.append('L');
+ buf.append(name);
+ argumentStack *= 2;
+ }
+
+ @Override
+ public void visitInnerClassType(final String name) {
+ endArguments();
+ buf.append('.');
+ buf.append(name);
+ argumentStack *= 2;
+ }
+
+ @Override
+ public void visitTypeArgument() {
+ if (argumentStack % 2 == 0) {
+ ++argumentStack;
+ buf.append('<');
+ }
+ buf.append('*');
+ }
+
+ @Override
+ public SignatureVisitor visitTypeArgument(final char wildcard) {
+ if (argumentStack % 2 == 0) {
+ ++argumentStack;
+ buf.append('<');
+ }
+ if (wildcard != '=') {
+ buf.append(wildcard);
+ }
+ return this;
+ }
+
+ @Override
+ public void visitEnd() {
+ endArguments();
+ buf.append(';');
+ }
+
+ /**
+ * Returns the signature that was built by this signature writer.
+ *
+ * @return the signature that was built by this signature writer.
+ */
+ @Override
+ public String toString() {
+ return buf.toString();
+ }
+
+ // ------------------------------------------------------------------------
+ // Utility methods
+ // ------------------------------------------------------------------------
+
+ /**
+ * Ends the formal type parameters section of the signature.
+ */
+ private void endFormals() {
+ if (hasFormals) {
+ hasFormals = false;
+ buf.append('>');
+ }
+ }
+
+ /**
+ * Ends the type arguments of a class or inner class type.
+ */
+ private void endArguments() {
+ if (argumentStack % 2 != 0) {
+ buf.append('>');
+ }
+ argumentStack /= 2;
+ }
+}
\ No newline at end of file
diff --git a/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java b/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java
index 71faae08..10ddecc8 100644
--- a/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java
+++ b/src/libbluray/bdj/java/org/videolan/BDJClassFileTransformer.java
@@ -32,15 +32,48 @@ package org.videolan;
* in class file com/tcs/blr/bluray/pal/fox/controller/d
*/
+import java.util.Map;
+
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Attribute;
+import org.objectweb.asm.commons.SimpleRemapper;
+import org.objectweb.asm.commons.RemappingClassAdapter;
-class BDJClassFileTransformer
+public class BDJClassFileTransformer
{
+ public byte[] rename(byte[] b, int off, int len, Map mappings)
+ throws ClassFormatError
+ {
+ byte[] r = new byte[len];
+ for (int i = 0; i < len; i++)
+ r[i] = b[i+off];
+
+ return rename(r, mappings);
+ }
+
+ public byte[] rename(byte[] b, Map mappings)
+ throws ClassFormatError
+ {
+ logger.info("Trying to rename class (" + b.length + " bytes)");
+
+ try {
+ SimpleRemapper m = new SimpleRemapper(mappings);
+ ClassReader cr = new ClassReader(b);
+ ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES/* | ClassWriter.COMPUTE_MAXS*/);
+ ClassVisitor cv = new RemappingClassAdapter(cw, m);
+ cr.accept(cv, ClassReader.SKIP_DEBUG);
+ return cw.toByteArray();
+ } catch (Exception e) {
+ logger.error("Failed renaming class: " + e);
+ }
+
+ return null;
+ }
+
public byte[] strip(byte[] b, int off, int len)
throws ClassFormatError
{
diff --git a/src/libbluray/bdj/java/org/videolan/mmbd/Adapter.java b/src/libbluray/bdj/java/org/videolan/mmbd/Adapter.java
new file mode 100644
index 00000000..da862b40
--- /dev/null
+++ b/src/libbluray/bdj/java/org/videolan/mmbd/Adapter.java
@@ -0,0 +1,241 @@
+/*
+ * This file is part of libbluray
+ * Copyright (C) 2017 VideoLAN
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * .
+ */
+
+/*
+ * BD-J support classes for libmmbd
+ */
+
+package org.videolan.mmbd;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.videolan.BDJClassFileTransformer;
+import org.videolan.BDJClassLoaderAdapter;
+import org.videolan.Logger;
+
+import javax.media.ClockStartedError;
+import javax.media.Manager;
+import javax.media.NoPlayerException;
+import javax.media.Player;
+import javax.tv.xlet.Xlet;
+import javax.tv.xlet.XletContext;
+import javax.tv.xlet.XletStateChangeException;
+import org.bluray.bdplus.StatusListener;
+
+public class Adapter implements BDJClassLoaderAdapter {
+
+ public Map getHideClasses() {
+ return null;
+ }
+
+ public Map getBootClasses() {
+ return bootClasses;
+ }
+
+ public Map getXletClasses() {
+ return xletClasses;
+ }
+
+ public Adapter() throws ClassNotFoundException {
+ /* relocate classes to avoid runtime package collisions */
+
+ final String s1 = "org/videolan/mmbd/Adapter$Xlet";
+ final String s2 = "org/videolan/mmbd/Adapter$If";
+ Map m = new HashMap();
+ String d1, d2;
+ m.put(s1, d1 = (new String(b0) + new String(b1)));
+ m.put(s2, d2 = (new String(b0) + new String(b2)));
+
+ BDJClassFileTransformer t = new BDJClassFileTransformer();
+ byte[] c1 = t.rename(loadBootClassCode(s1), m);
+ byte[] c2 = t.rename(loadBootClassCode(s2), m);
+
+ if (c1 != null) {
+ bootClasses = new HashMap();
+ bootClasses.put(d1.replace('/', '.'), c1);
+ }
+ if (c2 != null) {
+ xletClasses = new HashMap();
+ xletClasses.put(d2.replace('/', '.'), c2);
+ }
+ }
+
+ public static abstract class If {
+ protected If() {}
+ }
+
+ public static class Xlet implements StatusListener {
+ private static Xlet instance = new Xlet();
+ private javax.tv.xlet.Xlet xlet = null;
+ private XletContext ctx = null;
+
+ static private void log(String s) {
+ System.out.println(s);
+ }
+ static private void error(String s) {
+ System.err.println(s);
+ }
+
+ public static Xlet initXlet(javax.tv.xlet.Xlet xlet, XletContext ctx) throws XletStateChangeException {
+ if ((xlet == null) || (ctx == null)) {
+ error("initXlet: null argument");
+ throw new XletStateChangeException();
+ }
+ if ((instance.xlet == xlet) && (instance.ctx == ctx)) {
+ error("initXlet: invalid arguments");
+ throw new XletStateChangeException();
+ }
+ log("initXlet");
+ instance.xlet = xlet;
+ instance.ctx = ctx;
+ return instance;
+ }
+
+ public static Xlet lookup(XletContext ctx) {
+ return instance;
+ }
+
+ public void startXlet() throws XletStateChangeException {
+ }
+
+ public void pauseXlet() {
+ }
+
+ public void destroyXlet(boolean a) {
+ this.instance.xlet = null;
+ this.instance.ctx = null;
+ }
+
+ public boolean isAuthRequired() {
+ log("isAuthRequired");
+ return false;
+ }
+
+ public void doAuth() throws InterruptedException {
+ doAuth(null);
+ }
+
+ public synchronized void doAuth(If a) throws InterruptedException, RuntimeException {
+ error("doAuth");
+ }
+
+ public void destroy() {
+ }
+
+ public void receive(int i) {
+ }
+
+ public byte[] getMMV() {
+ byte[] b = new byte[8];
+ new java.util.Random().nextBytes(b);
+ log("getMMV");
+ return b;
+ }
+
+ public Player createPlayer(javax.media.protocol.DataSource s) throws IOException, NoPlayerException {
+ return Manager.createPlayer(s);
+ }
+
+ public Player createPlayer(javax.media.MediaLocator l) throws IOException, NoPlayerException {
+ return Manager.createPlayer(l);
+ }
+
+ public Player createPlayer(java.net.URL u) throws IOException, NoPlayerException {
+ return Manager.createPlayer(u);
+ }
+
+ public void destroyPlayer(Player p) {
+ if (p == null)
+ return;
+ p.stop();
+ try {
+ p.deallocate();
+ } catch (ClockStartedError localClockStartedError) {
+ }
+ p.close();
+ }
+ }
+
+ /*
+ * class loader
+ */
+
+ private final byte[] b0 = {99,111,109,47,109,97,99,114,111,118,105,115,105,111,110,47,98,100,112,108,117,115,47};
+ private final byte[] b1 = {77,86,67,111,109,109};
+ private final byte[] b2 = {83,116,114,101,101,116,76,111,99,107,71,101,116,116,101,114};
+
+ private byte[] loadBootClassCode(String name) throws ClassNotFoundException {
+ final String path = name.replace('.', '/').concat(".class");
+ InputStream is = null;
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ byte[] buffer = new byte[0xffff];
+ try {
+ is = (InputStream)
+ AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ return ClassLoader.getSystemResourceAsStream(path);
+ }
+ });
+
+ if (is == null) {
+ logger.error("loadBootClassCode(" + name + "): not found");
+ throw new ClassNotFoundException(name);
+ }
+
+ while (true) {
+ int r = is.read(buffer);
+ if (r == -1) {
+ break;
+ }
+ os.write(buffer, 0, r);
+ }
+
+ return os.toByteArray();
+
+ } catch (Exception e) {
+ logger.error("loadBootClassCode(" + name + ") failed: " + e);
+ throw new ClassNotFoundException(name);
+
+ } finally {
+ try {
+ if (is != null)
+ is.close();
+ } catch (IOException ioe) {
+ }
+ try {
+ if (os != null)
+ os.close();
+ } catch (IOException ioe) {
+ }
+ }
+ }
+
+ private Map bootClasses = new HashMap();
+ private Map xletClasses = new HashMap();
+
+ private static final Logger logger = Logger.getLogger(Adapter.class.getName());
+}