You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by ka...@apache.org on 2014/03/25 19:30:00 UTC
[12/23] FIXED - TAP5-2214: Make tapestry5 java8 compatible - update
ASM source to 5.0.1, should be jdk 1.5 compatible,
see ASM bug "317132 ASM 5.0 do not supported JDK 1.5?"
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/ClassConstantsCollector.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/ClassConstantsCollector.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/ClassConstantsCollector.java
new file mode 100644
index 0000000..b907322
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/ClassConstantsCollector.java
@@ -0,0 +1,198 @@
+/***
+ * 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.apache.tapestry5.internal.plastic.asm.optimizer;
+
+import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Attribute;
+import org.apache.tapestry5.internal.plastic.asm.ClassVisitor;
+import org.apache.tapestry5.internal.plastic.asm.FieldVisitor;
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+import org.apache.tapestry5.internal.plastic.asm.TypePath;
+
+/**
+ * A {@link ClassVisitor} that collects the {@link Constant}s of the classes it
+ * visits.
+ *
+ * @author Eric Bruneton
+ */
+public class ClassConstantsCollector extends ClassVisitor {
+
+ private final ConstantPool cp;
+
+ public ClassConstantsCollector(final ClassVisitor cv, final ConstantPool cp) {
+ super(Opcodes.ASM5, cv);
+ this.cp = cp;
+ }
+
+ @Override
+ public void visit(final int version, final int access, final String name,
+ final String signature, final String superName,
+ final String[] interfaces) {
+ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+ cp.newUTF8("Deprecated");
+ }
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ cp.newUTF8("Synthetic");
+ }
+ cp.newClass(name);
+ if (signature != null) {
+ cp.newUTF8("Signature");
+ cp.newUTF8(signature);
+ }
+ if (superName != null) {
+ cp.newClass(superName);
+ }
+ if (interfaces != null) {
+ for (int i = 0; i < interfaces.length; ++i) {
+ cp.newClass(interfaces[i]);
+ }
+ }
+ cv.visit(version, access, name, signature, superName, interfaces);
+ }
+
+ @Override
+ public void visitSource(final String source, final String debug) {
+ if (source != null) {
+ cp.newUTF8("SourceFile");
+ cp.newUTF8(source);
+ }
+ if (debug != null) {
+ cp.newUTF8("SourceDebugExtension");
+ }
+ cv.visitSource(source, debug);
+ }
+
+ @Override
+ public void visitOuterClass(final String owner, final String name,
+ final String desc) {
+ cp.newUTF8("EnclosingMethod");
+ cp.newClass(owner);
+ if (name != null && desc != null) {
+ cp.newNameType(name, desc);
+ }
+ cv.visitOuterClass(owner, name, desc);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleAnnotations");
+ }
+ return new AnnotationConstantsCollector(cv.visitAnnotation(desc,
+ visible), cp);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleTypeAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleTypeAnnotations");
+ }
+ return new AnnotationConstantsCollector(cv.visitAnnotation(desc,
+ visible), cp);
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attr) {
+ // can do nothing
+ cv.visitAttribute(attr);
+ }
+
+ @Override
+ public void visitInnerClass(final String name, final String outerName,
+ final String innerName, final int access) {
+ cp.newUTF8("InnerClasses");
+ if (name != null) {
+ cp.newClass(name);
+ }
+ if (outerName != null) {
+ cp.newClass(outerName);
+ }
+ if (innerName != null) {
+ cp.newUTF8(innerName);
+ }
+ cv.visitInnerClass(name, outerName, innerName, access);
+ }
+
+ @Override
+ public FieldVisitor visitField(final int access, final String name,
+ final String desc, final String signature, final Object value) {
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ cp.newUTF8("Synthetic");
+ }
+ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+ cp.newUTF8("Deprecated");
+ }
+ cp.newUTF8(name);
+ cp.newUTF8(desc);
+ if (signature != null) {
+ cp.newUTF8("Signature");
+ cp.newUTF8(signature);
+ }
+ if (value != null) {
+ cp.newConst(value);
+ }
+ return new FieldConstantsCollector(cv.visitField(access, name, desc,
+ signature, value), cp);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(final int access, final String name,
+ final String desc, final String signature, final String[] exceptions) {
+ if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
+ cp.newUTF8("Synthetic");
+ }
+ if ((access & Opcodes.ACC_DEPRECATED) != 0) {
+ cp.newUTF8("Deprecated");
+ }
+ cp.newUTF8(name);
+ cp.newUTF8(desc);
+ if (signature != null) {
+ cp.newUTF8("Signature");
+ cp.newUTF8(signature);
+ }
+ if (exceptions != null) {
+ cp.newUTF8("Exceptions");
+ for (int i = 0; i < exceptions.length; ++i) {
+ cp.newClass(exceptions[i]);
+ }
+ }
+ return new MethodConstantsCollector(cv.visitMethod(access, name, desc,
+ signature, exceptions), cp);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/ClassOptimizer.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/ClassOptimizer.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/ClassOptimizer.java
new file mode 100644
index 0000000..f4a7a22
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/ClassOptimizer.java
@@ -0,0 +1,260 @@
+/***
+ * 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.apache.tapestry5.internal.plastic.asm.optimizer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Attribute;
+import org.apache.tapestry5.internal.plastic.asm.ClassVisitor;
+import org.apache.tapestry5.internal.plastic.asm.FieldVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Label;
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+import org.apache.tapestry5.internal.plastic.asm.TypePath;
+import org.apache.tapestry5.internal.plastic.asm.commons.Remapper;
+import org.apache.tapestry5.internal.plastic.asm.commons.RemappingClassAdapter;
+
+/**
+ * A {@link ClassVisitor} that renames fields and methods, and removes debug
+ * info.
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public class ClassOptimizer extends RemappingClassAdapter {
+
+ private String pkgName;
+ String clsName;
+
+ boolean isInterface = false;
+ boolean hasClinitMethod = false;
+ List<String> syntheticClassFields = new ArrayList<String>();
+
+ public ClassOptimizer(final ClassVisitor cv, final Remapper remapper) {
+ super(Opcodes.ASM5, cv, remapper);
+ }
+
+ FieldVisitor syntheticFieldVisitor(final int access, final String name,
+ final String desc) {
+ return super.visitField(access, name, desc, null, null);
+ }
+
+ // ------------------------------------------------------------------------
+ // Overridden methods
+ // ------------------------------------------------------------------------
+
+ @Override
+ public void visit(final int version, final int access, final String name,
+ final String signature, final String superName,
+ final String[] interfaces) {
+ super.visit(Opcodes.V1_2, access, name, null, superName, interfaces);
+ int index = name.lastIndexOf('/');
+ if (index > 0) {
+ pkgName = name.substring(0, index);
+ } else {
+ pkgName = "";
+ }
+ clsName = name;
+ isInterface = (access & Opcodes.ACC_INTERFACE) != 0;
+ }
+
+ @Override
+ public void visitSource(final String source, final String debug) {
+ // remove debug info
+ }
+
+ @Override
+ public void visitOuterClass(final String owner, final String name,
+ final String desc) {
+ // remove debug info
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
+ // remove annotations
+ return null;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ // remove annotations
+ return null;
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attr) {
+ // remove non standard attributes
+ }
+
+ @Override
+ public void visitInnerClass(final String name, final String outerName,
+ final String innerName, final int access) {
+ // remove debug info
+ }
+
+ @Override
+ public FieldVisitor visitField(final int access, final String name,
+ final String desc, final String signature, final Object value) {
+ String s = remapper.mapFieldName(className, name, desc);
+ if ("-".equals(s)) {
+ return null;
+ }
+ if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) {
+ if ((access & Opcodes.ACC_FINAL) != 0
+ && (access & Opcodes.ACC_STATIC) != 0 && desc.length() == 1) {
+ return null;
+ }
+ if ("org/objectweb/asm".equals(pkgName) && s.equals(name)) {
+ System.out.println("INFO: " + clsName + "." + s
+ + " could be renamed");
+ }
+ super.visitField(access, name, desc, null, value);
+ } else {
+ if (!s.equals(name)) {
+ throw new RuntimeException("The public or protected field "
+ + className + '.' + name + " must not be renamed.");
+ }
+ super.visitField(access, name, desc, null, value);
+ }
+ return null; // remove debug info
+ }
+
+ @Override
+ public MethodVisitor visitMethod(final int access, final String name,
+ final String desc, final String signature, final String[] exceptions) {
+ String s = remapper.mapMethodName(className, name, desc);
+ if ("-".equals(s)) {
+ return null;
+ }
+ if (name.equals("<clinit>") && !isInterface) {
+ hasClinitMethod = true;
+ MethodVisitor mv = super.visitMethod(access, name, desc, null,
+ exceptions);
+ return new MethodVisitor(Opcodes.ASM5, mv) {
+ @Override
+ public void visitCode() {
+ super.visitCode();
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, clsName,
+ "_clinit_", "()V", false);
+ }
+ };
+ }
+
+ if ((access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED)) == 0) {
+ if ("org/objectweb/asm".equals(pkgName) && !name.startsWith("<")
+ && s.equals(name)) {
+ System.out.println("INFO: " + clsName + "." + s
+ + " could be renamed");
+ }
+ return super.visitMethod(access, name, desc, null, exceptions);
+ } else {
+ if (!s.equals(name)) {
+ throw new RuntimeException("The public or protected method "
+ + className + '.' + name + desc
+ + " must not be renamed.");
+ }
+ return super.visitMethod(access, name, desc, null, exceptions);
+ }
+ }
+
+ @Override
+ protected MethodVisitor createRemappingMethodAdapter(int access,
+ String newDesc, MethodVisitor mv) {
+ return new MethodOptimizer(this, access, newDesc, mv, remapper);
+ }
+
+ @Override
+ public void visitEnd() {
+ if (syntheticClassFields.isEmpty()) {
+ if (hasClinitMethod) {
+ MethodVisitor mv = cv.visitMethod(Opcodes.ACC_STATIC
+ | Opcodes.ACC_SYNTHETIC, "_clinit_", "()V", null, null);
+ mv.visitCode();
+ mv.visitInsn(Opcodes.RETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+ } else {
+ MethodVisitor mv = cv.visitMethod(Opcodes.ACC_STATIC
+ | Opcodes.ACC_SYNTHETIC, "class$",
+ "(Ljava/lang/String;)Ljava/lang/Class;", null, null);
+ mv.visitCode();
+ Label l0 = new Label();
+ Label l1 = new Label();
+ Label l2 = new Label();
+ mv.visitTryCatchBlock(l0, l1, l2,
+ "java/lang/ClassNotFoundException");
+ mv.visitLabel(l0);
+ mv.visitVarInsn(Opcodes.ALOAD, 0);
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Class",
+ "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);
+ mv.visitLabel(l1);
+ mv.visitInsn(Opcodes.ARETURN);
+ mv.visitLabel(l2);
+ mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
+ "java/lang/ClassNotFoundException", "getMessage",
+ "()Ljava/lang/String;", false);
+ mv.visitVarInsn(Opcodes.ASTORE, 1);
+ mv.visitTypeInsn(Opcodes.NEW, "java/lang/NoClassDefFoundError");
+ mv.visitInsn(Opcodes.DUP);
+ mv.visitVarInsn(Opcodes.ALOAD, 1);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
+ "java/lang/NoClassDefFoundError", "<init>",
+ "(Ljava/lang/String;)V", false);
+ mv.visitInsn(Opcodes.ATHROW);
+ mv.visitMaxs(3, 2);
+ mv.visitEnd();
+
+ if (hasClinitMethod) {
+ mv = cv.visitMethod(Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE,
+ "_clinit_", "()V", null, null);
+ } else {
+ mv = cv.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V",
+ null, null);
+ }
+ for (String ldcName : syntheticClassFields) {
+ String fieldName = "class$" + ldcName.replace('/', '$');
+ mv.visitLdcInsn(ldcName.replace('/', '.'));
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, clsName, "class$",
+ "(Ljava/lang/String;)Ljava/lang/Class;", false);
+ mv.visitFieldInsn(Opcodes.PUTSTATIC, clsName, fieldName,
+ "Ljava/lang/Class;");
+ }
+ mv.visitInsn(Opcodes.RETURN);
+ mv.visitMaxs(1, 0);
+ mv.visitEnd();
+ }
+ super.visitEnd();
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/Constant.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/Constant.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/Constant.java
new file mode 100644
index 0000000..9c1f306
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/Constant.java
@@ -0,0 +1,323 @@
+/***
+ * 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.apache.tapestry5.internal.plastic.asm.optimizer;
+
+import java.util.Arrays;
+
+import org.apache.tapestry5.internal.plastic.asm.ClassWriter;
+import org.apache.tapestry5.internal.plastic.asm.Handle;
+
+/**
+ * A constant pool item.
+ *
+ * @author Eric Bruneton
+ */
+class Constant {
+
+ /**
+ * Type of this constant pool item. A single class is used to represent all
+ * constant pool item types, in order to minimize the bytecode size of this
+ * package. The value of this field is I, J, F, D, S, s, C, T, G, M, N, y,
+ * t, [h..p] (for Constant Integer, Long, Float, Double, STR, UTF8, Class,
+ * NameType, Fieldref, Methodref, InterfaceMethodref, InvokeDynamic,
+ * MethodType and MethodHandle constant pool items respectively).
+ *
+ * The 9 variable of MethodHandle constants are stored between h and p.
+ */
+ char type;
+
+ /**
+ * Value of this item, for an integer item.
+ */
+ int intVal;
+
+ /**
+ * Value of this item, for a long item.
+ */
+ long longVal;
+
+ /**
+ * Value of this item, for a float item.
+ */
+ float floatVal;
+
+ /**
+ * Value of this item, for a double item.
+ */
+ double doubleVal;
+
+ /**
+ * First part of the value of this item, for items that do not hold a
+ * primitive value.
+ */
+ String strVal1;
+
+ /**
+ * Second part of the value of this item, for items that do not hold a
+ * primitive value.
+ */
+ String strVal2;
+
+ /**
+ * Third part of the value of this item, for items that do not hold a
+ * primitive value.
+ */
+ Object objVal3;
+
+ /**
+ * InvokeDynamic's constant values.
+ */
+ Object[] objVals;
+
+ /**
+ * The hash code value of this constant pool item.
+ */
+ int hashCode;
+
+ Constant() {
+ }
+
+ Constant(final Constant i) {
+ type = i.type;
+ intVal = i.intVal;
+ longVal = i.longVal;
+ floatVal = i.floatVal;
+ doubleVal = i.doubleVal;
+ strVal1 = i.strVal1;
+ strVal2 = i.strVal2;
+ objVal3 = i.objVal3;
+ objVals = i.objVals;
+ hashCode = i.hashCode;
+ }
+
+ /**
+ * Sets this item to an integer item.
+ *
+ * @param intVal
+ * the value of this item.
+ */
+ void set(final int intVal) {
+ this.type = 'I';
+ this.intVal = intVal;
+ this.hashCode = 0x7FFFFFFF & (type + intVal);
+ }
+
+ /**
+ * Sets this item to a long item.
+ *
+ * @param longVal
+ * the value of this item.
+ */
+ void set(final long longVal) {
+ this.type = 'J';
+ this.longVal = longVal;
+ this.hashCode = 0x7FFFFFFF & (type + (int) longVal);
+ }
+
+ /**
+ * Sets this item to a float item.
+ *
+ * @param floatVal
+ * the value of this item.
+ */
+ void set(final float floatVal) {
+ this.type = 'F';
+ this.floatVal = floatVal;
+ this.hashCode = 0x7FFFFFFF & (type + (int) floatVal);
+ }
+
+ /**
+ * Sets this item to a double item.
+ *
+ * @param doubleVal
+ * the value of this item.
+ */
+ void set(final double doubleVal) {
+ this.type = 'D';
+ this.doubleVal = doubleVal;
+ this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal);
+ }
+
+ /**
+ * Sets this item to an item that do not hold a primitive value.
+ *
+ * @param type
+ * the type of this item.
+ * @param strVal1
+ * first part of the value of this item.
+ * @param strVal2
+ * second part of the value of this item.
+ * @param strVal3
+ * third part of the value of this item.
+ */
+ void set(final char type, final String strVal1, final String strVal2,
+ final String strVal3) {
+ this.type = type;
+ this.strVal1 = strVal1;
+ this.strVal2 = strVal2;
+ this.objVal3 = strVal3;
+ switch (type) {
+ case 's':
+ case 'S':
+ case 'C':
+ case 't':
+ hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
+ return;
+ case 'T':
+ hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+ * strVal2.hashCode());
+ return;
+ // case 'G':
+ // case 'M':
+ // case 'N':
+ // case 'h' ... 'p':
+ default:
+ hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()
+ * strVal2.hashCode() * strVal3.hashCode());
+ }
+ }
+
+ /**
+ * Set this item to an InvokeDynamic item.
+ *
+ * @param name
+ * invokedynamic's name.
+ * @param desc
+ * invokedynamic's descriptor.
+ * @param bsm
+ * bootstrap method.
+ * @param bsmArgs
+ * bootstrap method constant arguments.
+ */
+ void set(final String name, final String desc, final Handle bsm,
+ final Object[] bsmArgs) {
+ this.type = 'y';
+ this.strVal1 = name;
+ this.strVal2 = desc;
+ this.objVal3 = bsm;
+ this.objVals = bsmArgs;
+
+ int hashCode = 'y' + name.hashCode() * desc.hashCode() * bsm.hashCode();
+ for (int i = 0; i < bsmArgs.length; i++) {
+ hashCode *= bsmArgs[i].hashCode();
+ }
+ this.hashCode = 0x7FFFFFFF & hashCode;
+ }
+
+ void write(final ClassWriter cw) {
+ switch (type) {
+ case 'I':
+ cw.newConst(new Integer(intVal));
+ break;
+ case 'J':
+ cw.newConst(new Long(longVal));
+ break;
+ case 'F':
+ cw.newConst(new Float(floatVal));
+ break;
+ case 'D':
+ cw.newConst(new Double(doubleVal));
+ break;
+ case 'S':
+ cw.newConst(strVal1);
+ break;
+ case 's':
+ cw.newUTF8(strVal1);
+ break;
+ case 'C':
+ cw.newClass(strVal1);
+ break;
+ case 'T':
+ cw.newNameType(strVal1, strVal2);
+ break;
+ case 'G':
+ cw.newField(strVal1, strVal2, (String) objVal3);
+ break;
+ case 'M':
+ cw.newMethod(strVal1, strVal2, (String) objVal3, false);
+ break;
+ case 'N':
+ cw.newMethod(strVal1, strVal2, (String) objVal3, true);
+ break;
+ case 'y':
+ cw.newInvokeDynamic(strVal1, strVal2, (Handle) objVal3, objVals);
+ break;
+ case 't':
+ cw.newMethodType(strVal1);
+ break;
+ default: // 'h' ... 'p': handle
+ cw.newHandle(type - 'h' + 1, strVal1, strVal2, (String) objVal3);
+ }
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (!(o instanceof Constant)) {
+ return false;
+ }
+ Constant c = (Constant) o;
+ if (c.type == type) {
+ switch (type) {
+ case 'I':
+ return c.intVal == intVal;
+ case 'J':
+ return c.longVal == longVal;
+ case 'F':
+ return Float.compare(c.floatVal, floatVal) == 0;
+ case 'D':
+ return Double.compare(c.doubleVal, doubleVal) == 0;
+ case 's':
+ case 'S':
+ case 'C':
+ case 't':
+ return c.strVal1.equals(strVal1);
+ case 'T':
+ return c.strVal1.equals(strVal1) && c.strVal2.equals(strVal2);
+ case 'y':
+ return c.strVal1.equals(strVal1) && c.strVal2.equals(strVal2)
+ && c.objVal3.equals(objVal3)
+ && Arrays.equals(c.objVals, objVals);
+ // case 'G':
+ // case 'M':
+ // case 'N':
+ // case 'h' ... 'p':
+ default:
+ return c.strVal1.equals(strVal1) && c.strVal2.equals(strVal2)
+ && c.objVal3.equals(objVal3);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return hashCode;
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/ConstantPool.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/ConstantPool.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/ConstantPool.java
new file mode 100644
index 0000000..1901387
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/ConstantPool.java
@@ -0,0 +1,249 @@
+/***
+ * 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.apache.tapestry5.internal.plastic.asm.optimizer;
+
+import java.util.HashMap;
+
+import org.apache.tapestry5.internal.plastic.asm.Handle;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+import org.apache.tapestry5.internal.plastic.asm.Type;
+
+/**
+ * A constant pool.
+ *
+ * @author Eric Bruneton
+ */
+public class ConstantPool extends HashMap<Constant, Constant> {
+
+ private final Constant key1 = new Constant();
+
+ private final Constant key2 = new Constant();
+
+ private final Constant key3 = new Constant();
+
+ private final Constant key4 = new Constant();
+
+ private final Constant key5 = new Constant();
+
+ public Constant newInteger(final int value) {
+ key1.set(value);
+ Constant result = get(key1);
+ if (result == null) {
+ result = new Constant(key1);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newFloat(final float value) {
+ key1.set(value);
+ Constant result = get(key1);
+ if (result == null) {
+ result = new Constant(key1);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newLong(final long value) {
+ key1.set(value);
+ Constant result = get(key1);
+ if (result == null) {
+ result = new Constant(key1);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newDouble(final double value) {
+ key1.set(value);
+ Constant result = get(key1);
+ if (result == null) {
+ result = new Constant(key1);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newUTF8(final String value) {
+ key1.set('s', value, null, null);
+ Constant result = get(key1);
+ if (result == null) {
+ result = new Constant(key1);
+ put(result);
+ }
+ return result;
+ }
+
+ private Constant newString(final String value) {
+ key2.set('S', value, null, null);
+ Constant result = get(key2);
+ if (result == null) {
+ newUTF8(value);
+ result = new Constant(key2);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newClass(final String value) {
+ key2.set('C', value, null, null);
+ Constant result = get(key2);
+ if (result == null) {
+ newUTF8(value);
+ result = new Constant(key2);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newMethodType(final String methodDescriptor) {
+ key2.set('t', methodDescriptor, null, null);
+ Constant result = get(key2);
+ if (result == null) {
+ newUTF8(methodDescriptor);
+ result = new Constant(key2);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newHandle(final int tag, final String owner,
+ final String name, final String desc) {
+ key4.set((char) ('h' - 1 + tag), owner, name, desc);
+ Constant result = get(key4);
+ if (result == null) {
+ if (tag <= Opcodes.H_PUTSTATIC) {
+ newField(owner, name, desc);
+ } else {
+ newMethod(owner, name, desc, tag == Opcodes.H_INVOKEINTERFACE);
+ }
+ result = new Constant(key4);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newConst(final Object cst) {
+ if (cst instanceof Integer) {
+ int val = ((Integer) cst).intValue();
+ return newInteger(val);
+ } else if (cst instanceof Float) {
+ float val = ((Float) cst).floatValue();
+ return newFloat(val);
+ } else if (cst instanceof Long) {
+ long val = ((Long) cst).longValue();
+ return newLong(val);
+ } else if (cst instanceof Double) {
+ double val = ((Double) cst).doubleValue();
+ return newDouble(val);
+ } else if (cst instanceof String) {
+ return newString((String) cst);
+ } else if (cst instanceof Type) {
+ Type t = (Type) cst;
+ int s = t.getSort();
+ if (s == Type.OBJECT) {
+ return newClass(t.getInternalName());
+ } else if (s == Type.METHOD) {
+ return newMethodType(t.getDescriptor());
+ } else { // s == primitive type or array
+ return newClass(t.getDescriptor());
+ }
+ } else if (cst instanceof Handle) {
+ Handle h = (Handle) cst;
+ return newHandle(h.getTag(), h.getOwner(), h.getName(), h.getDesc());
+ } else {
+ throw new IllegalArgumentException("value " + cst);
+ }
+ }
+
+ public Constant newField(final String owner, final String name,
+ final String desc) {
+ key3.set('G', owner, name, desc);
+ Constant result = get(key3);
+ if (result == null) {
+ newClass(owner);
+ newNameType(name, desc);
+ result = new Constant(key3);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newMethod(final String owner, final String name,
+ final String desc, final boolean itf) {
+ key3.set(itf ? 'N' : 'M', owner, name, desc);
+ Constant result = get(key3);
+ if (result == null) {
+ newClass(owner);
+ newNameType(name, desc);
+ result = new Constant(key3);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newInvokeDynamic(String name, String desc, Handle bsm,
+ Object... bsmArgs) {
+ key5.set(name, desc, bsm, bsmArgs);
+ Constant result = get(key5);
+ if (result == null) {
+ newNameType(name, desc);
+ newHandle(bsm.getTag(), bsm.getOwner(), bsm.getName(),
+ bsm.getDesc());
+ for (int i = 0; i < bsmArgs.length; i++) {
+ newConst(bsmArgs[i]);
+ }
+ result = new Constant(key5);
+ put(result);
+ }
+ return result;
+ }
+
+ public Constant newNameType(final String name, final String desc) {
+ key2.set('T', name, desc, null);
+ Constant result = get(key2);
+ if (result == null) {
+ newUTF8(name);
+ newUTF8(desc);
+ result = new Constant(key2);
+ put(result);
+ }
+ return result;
+ }
+
+ private Constant get(final Constant key) {
+ return get((Object) key);
+ }
+
+ private void put(final Constant cst) {
+ put(cst, cst);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/FieldConstantsCollector.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/FieldConstantsCollector.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/FieldConstantsCollector.java
new file mode 100644
index 0000000..63ca654
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/FieldConstantsCollector.java
@@ -0,0 +1,89 @@
+/***
+ * 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.apache.tapestry5.internal.plastic.asm.optimizer;
+
+import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Attribute;
+import org.apache.tapestry5.internal.plastic.asm.FieldVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+import org.apache.tapestry5.internal.plastic.asm.TypePath;
+
+/**
+ * A {@link FieldVisitor} that collects the {@link Constant}s of the fields it
+ * visits.
+ *
+ * @author Eric Bruneton
+ */
+public class FieldConstantsCollector extends FieldVisitor {
+
+ private final ConstantPool cp;
+
+ public FieldConstantsCollector(final FieldVisitor fv, final ConstantPool cp) {
+ super(Opcodes.ASM5, fv);
+ this.cp = cp;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleAnnotations");
+ }
+ return new AnnotationConstantsCollector(fv.visitAnnotation(desc,
+ visible), cp);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleTypeAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleTypeAnnotations");
+ }
+ return new AnnotationConstantsCollector(fv.visitAnnotation(desc,
+ visible), cp);
+ }
+
+ @Override
+ public void visitAttribute(final Attribute attr) {
+ // can do nothing
+ fv.visitAttribute(attr);
+ }
+
+ @Override
+ public void visitEnd() {
+ fv.visitEnd();
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/JarOptimizer.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/JarOptimizer.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/JarOptimizer.java
new file mode 100644
index 0000000..e7d93cf
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/JarOptimizer.java
@@ -0,0 +1,235 @@
+/***
+ * 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.apache.tapestry5.internal.plastic.asm.optimizer;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.tapestry5.internal.plastic.asm.ClassReader;
+import org.apache.tapestry5.internal.plastic.asm.ClassVisitor;
+import org.apache.tapestry5.internal.plastic.asm.FieldVisitor;
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+
+/**
+ * A Jar file optimizer.
+ *
+ * @author Eric Bruneton
+ */
+public class JarOptimizer {
+
+ static final Set<String> API = new HashSet<String>();
+ static final Map<String, String> HIERARCHY = new HashMap<String, String>();
+ static boolean nodebug = false;
+
+ public static void main(final String[] args) throws IOException {
+ File f = new File(args[0]);
+ InputStream is = new GZIPInputStream(new FileInputStream(f));
+ BufferedReader lnr = new LineNumberReader(new InputStreamReader(is));
+ while (true) {
+ String line = lnr.readLine();
+ if (line != null) {
+ if (line.startsWith("class")) {
+ String c = line.substring(6, line.lastIndexOf(' '));
+ String sc = line.substring(line.lastIndexOf(' ') + 1);
+ HIERARCHY.put(c, sc);
+ } else {
+ API.add(line);
+ }
+ } else {
+ break;
+ }
+ }
+
+ int argIndex = 1;
+ if (args[argIndex].equals("-nodebug")) {
+ nodebug = true;
+ argIndex++;
+ }
+
+ optimize(new File(args[argIndex]));
+ }
+
+ static void optimize(final File f) throws IOException {
+ if (nodebug && f.getName().contains("debug")) {
+ return;
+ }
+
+ if (f.isDirectory()) {
+ File[] files = f.listFiles();
+ for (int i = 0; i < files.length; ++i) {
+ optimize(files[i]);
+ }
+ } else if (f.getName().endsWith(".jar")) {
+ File g = new File(f.getParentFile(), f.getName() + ".new");
+ ZipFile zf = new ZipFile(f);
+ ZipOutputStream out = new ZipOutputStream(new FileOutputStream(g));
+ Enumeration<? extends ZipEntry> e = zf.entries();
+ byte[] buf = new byte[10000];
+ while (e.hasMoreElements()) {
+ ZipEntry ze = e.nextElement();
+ if (ze.isDirectory()) {
+ out.putNextEntry(ze);
+ continue;
+ }
+ out.putNextEntry(ze);
+ if (ze.getName().endsWith(".class")) {
+ ClassReader cr = new ClassReader(zf.getInputStream(ze));
+ // cr.accept(new ClassDump(), 0);
+ cr.accept(new ClassVerifier(), 0);
+ }
+ InputStream is = zf.getInputStream(ze);
+ int n;
+ do {
+ n = is.read(buf, 0, buf.length);
+ if (n != -1) {
+ out.write(buf, 0, n);
+ }
+ } while (n != -1);
+ out.closeEntry();
+ }
+ out.close();
+ zf.close();
+ if (!f.delete()) {
+ throw new IOException("Cannot delete file " + f);
+ }
+ if (!g.renameTo(f)) {
+ throw new IOException("Cannot rename file " + g);
+ }
+ }
+ }
+
+ static class ClassDump extends ClassVisitor {
+
+ String owner;
+
+ public ClassDump() {
+ super(Opcodes.ASM5);
+ }
+
+ @Override
+ public void visit(final int version, final int access,
+ final String name, final String signature,
+ final String superName, final String[] interfaces) {
+ owner = name;
+ if (owner.startsWith("java/")) {
+ System.out.println("class " + name + ' ' + superName);
+ }
+ }
+
+ @Override
+ public FieldVisitor visitField(final int access, final String name,
+ final String desc, final String signature, final Object value) {
+ if (owner.startsWith("java/")) {
+ System.out.println(owner + ' ' + name);
+ }
+ return null;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(final int access, final String name,
+ final String desc, final String signature,
+ final String[] exceptions) {
+ if (owner.startsWith("java/")) {
+ System.out.println(owner + ' ' + name + desc);
+ }
+ return null;
+ }
+ }
+
+ static class ClassVerifier extends ClassVisitor {
+
+ String owner;
+
+ String method;
+
+ public ClassVerifier() {
+ super(Opcodes.ASM5);
+ }
+
+ @Override
+ public void visit(final int version, final int access,
+ final String name, final String signature,
+ final String superName, final String[] interfaces) {
+ owner = name;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(final int access, final String name,
+ final String desc, final String signature,
+ final String[] exceptions) {
+ method = name + desc;
+ return new MethodVisitor(Opcodes.ASM5) {
+ @Override
+ public void visitFieldInsn(final int opcode,
+ final String owner, final String name, final String desc) {
+ check(owner, name);
+ }
+
+ @Override
+ public void visitMethodInsn(final int opcode,
+ final String owner, final String name,
+ final String desc, final boolean itf) {
+ check(owner, name + desc);
+ }
+ };
+ }
+
+ void check(String owner, String member) {
+ if (owner.startsWith("java/")) {
+ String o = owner;
+ while (o != null) {
+ if (API.contains(o + ' ' + member)) {
+ return;
+ }
+ o = HIERARCHY.get(o);
+ }
+ System.out.println("WARNING: " + owner + ' ' + member
+ + " called in " + this.owner + ' ' + method
+ + " is not defined in JDK 1.3 API");
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/MethodConstantsCollector.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/MethodConstantsCollector.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/MethodConstantsCollector.java
new file mode 100644
index 0000000..54b3519
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/MethodConstantsCollector.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.apache.tapestry5.internal.plastic.asm.optimizer;
+
+import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Handle;
+import org.apache.tapestry5.internal.plastic.asm.Label;
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+import org.apache.tapestry5.internal.plastic.asm.TypePath;
+
+/**
+ * An {@link MethodVisitor} that collects the {@link Constant}s of the methods
+ * it visits.
+ *
+ * @author Eric Bruneton
+ */
+public class MethodConstantsCollector extends MethodVisitor {
+
+ private final ConstantPool cp;
+
+ public MethodConstantsCollector(final MethodVisitor mv,
+ final ConstantPool cp) {
+ super(Opcodes.ASM5, mv);
+ this.cp = cp;
+ }
+
+ @Override
+ public void visitParameter(String name, int access) {
+ cp.newUTF8("MethodParameters");
+ if (name != null) {
+ cp.newUTF8(name);
+ }
+ mv.visitParameter(name, access);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ cp.newUTF8("AnnotationDefault");
+ return new AnnotationConstantsCollector(mv.visitAnnotationDefault(), cp);
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String desc,
+ final boolean visible) {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleAnnotations");
+ }
+ return new AnnotationConstantsCollector(mv.visitAnnotation(desc,
+ visible), cp);
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleTypeAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleTypeAnnotations");
+ }
+ return new AnnotationConstantsCollector(mv.visitAnnotation(desc,
+ visible), cp);
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(final int parameter,
+ final String desc, final boolean visible) {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleParameterAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleParameterAnnotations");
+ }
+ return new AnnotationConstantsCollector(mv.visitParameterAnnotation(
+ parameter, desc, visible), cp);
+ }
+
+ @Override
+ public void visitTypeInsn(final int opcode, final String type) {
+ cp.newClass(type);
+ mv.visitTypeInsn(opcode, type);
+ }
+
+ @Override
+ public void visitFieldInsn(final int opcode, final String owner,
+ final String name, final String desc) {
+ cp.newField(owner, name, desc);
+ mv.visitFieldInsn(opcode, owner, name, desc);
+ }
+
+ @Override
+ public void visitMethodInsn(final int opcode, final String owner,
+ final String name, final String desc, final boolean itf) {
+ cp.newMethod(owner, name, desc, itf);
+ mv.visitMethodInsn(opcode, owner, name, desc, itf);
+ }
+
+ @Override
+ public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
+ Object... bsmArgs) {
+ cp.newInvokeDynamic(name, desc, bsm, bsmArgs);
+ mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
+ }
+
+ @Override
+ public void visitLdcInsn(final Object cst) {
+ cp.newConst(cst);
+ mv.visitLdcInsn(cst);
+ }
+
+ @Override
+ public void visitMultiANewArrayInsn(final String desc, final int dims) {
+ cp.newClass(desc);
+ mv.visitMultiANewArrayInsn(desc, dims);
+ }
+
+ @Override
+ public AnnotationVisitor visitInsnAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleTypeAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleTypeAnnotations");
+ }
+ return new AnnotationConstantsCollector(mv.visitInsnAnnotation(typeRef,
+ typePath, desc, visible), cp);
+ }
+
+ @Override
+ public void visitTryCatchBlock(final Label start, final Label end,
+ final Label handler, final String type) {
+ if (type != null) {
+ cp.newClass(type);
+ }
+ mv.visitTryCatchBlock(start, end, handler, type);
+ }
+
+ @Override
+ public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleTypeAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleTypeAnnotations");
+ }
+ return new AnnotationConstantsCollector(mv.visitTryCatchAnnotation(
+ typeRef, typePath, desc, visible), cp);
+ }
+
+ @Override
+ public void visitLocalVariable(final String name, final String desc,
+ final String signature, final Label start, final Label end,
+ final int index) {
+ if (signature != null) {
+ cp.newUTF8("LocalVariableTypeTable");
+ cp.newUTF8(name);
+ cp.newUTF8(signature);
+ }
+ cp.newUTF8("LocalVariableTable");
+ cp.newUTF8(name);
+ cp.newUTF8(desc);
+ mv.visitLocalVariable(name, desc, signature, start, end, index);
+ }
+
+ @Override
+ public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
+ TypePath typePath, Label[] start, Label[] end, int[] index,
+ String desc, boolean visible) {
+ cp.newUTF8(desc);
+ if (visible) {
+ cp.newUTF8("RuntimeVisibleTypeAnnotations");
+ } else {
+ cp.newUTF8("RuntimeInvisibleTypeAnnotations");
+ }
+ return new AnnotationConstantsCollector(
+ mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
+ index, desc, visible), cp);
+ }
+
+ @Override
+ public void visitLineNumber(final int line, final Label start) {
+ cp.newUTF8("LineNumberTable");
+ mv.visitLineNumber(line, start);
+ }
+
+ @Override
+ public void visitMaxs(final int maxStack, final int maxLocals) {
+ cp.newUTF8("Code");
+ mv.visitMaxs(maxStack, maxLocals);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/MethodOptimizer.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/MethodOptimizer.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/MethodOptimizer.java
new file mode 100644
index 0000000..adad6b4
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/MethodOptimizer.java
@@ -0,0 +1,136 @@
+/***
+ * 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.apache.tapestry5.internal.plastic.asm.optimizer;
+
+import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Attribute;
+import org.apache.tapestry5.internal.plastic.asm.FieldVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Label;
+import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
+import org.apache.tapestry5.internal.plastic.asm.Opcodes;
+import org.apache.tapestry5.internal.plastic.asm.Type;
+import org.apache.tapestry5.internal.plastic.asm.TypePath;
+import org.apache.tapestry5.internal.plastic.asm.commons.Remapper;
+import org.apache.tapestry5.internal.plastic.asm.commons.RemappingMethodAdapter;
+
+/**
+ * A {@link MethodVisitor} that renames fields and methods, and removes debug
+ * info.
+ *
+ * @author Eugene Kuleshov
+ */
+public class MethodOptimizer extends RemappingMethodAdapter implements Opcodes {
+
+ private final ClassOptimizer classOptimizer;
+
+ public MethodOptimizer(ClassOptimizer classOptimizer, int access,
+ String desc, MethodVisitor mv, Remapper remapper) {
+ super(Opcodes.ASM5, access, desc, mv, remapper);
+ this.classOptimizer = classOptimizer;
+ }
+
+ // ------------------------------------------------------------------------
+ // Overridden methods
+ // ------------------------------------------------------------------------
+
+ @Override
+ public void visitParameter(String name, int access) {
+ // remove parameter info
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotationDefault() {
+ // remove annotations
+ return null;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ // remove annotations
+ return null;
+ }
+
+ @Override
+ public AnnotationVisitor visitTypeAnnotation(int typeRef,
+ TypePath typePath, String desc, boolean visible) {
+ return null;
+ }
+
+ @Override
+ public AnnotationVisitor visitParameterAnnotation(final int parameter,
+ final String desc, final boolean visible) {
+ // remove annotations
+ return null;
+ }
+
+ @Override
+ public void visitLocalVariable(final String name, final String desc,
+ final String signature, final Label start, final Label end,
+ final int index) {
+ // remove debug info
+ }
+
+ @Override
+ public void visitLineNumber(final int line, final Label start) {
+ // remove debug info
+ }
+
+ @Override
+ public void visitFrame(int type, int local, Object[] local2, int stack,
+ Object[] stack2) {
+ // remove frame info
+ }
+
+ @Override
+ public void visitAttribute(Attribute attr) {
+ // remove non standard attributes
+ }
+
+ @Override
+ public void visitLdcInsn(Object cst) {
+ if (!(cst instanceof Type)) {
+ super.visitLdcInsn(cst);
+ return;
+ }
+
+ // transform Foo.class for 1.2 compatibility
+ String ldcName = ((Type) cst).getInternalName();
+ String fieldName = "class$" + ldcName.replace('/', '$');
+ if (!classOptimizer.syntheticClassFields.contains(ldcName)) {
+ classOptimizer.syntheticClassFields.add(ldcName);
+ FieldVisitor fv = classOptimizer.syntheticFieldVisitor(ACC_STATIC
+ | ACC_SYNTHETIC, fieldName, "Ljava/lang/Class;");
+ fv.visitEnd();
+ }
+
+ String clsName = classOptimizer.clsName;
+ mv.visitFieldInsn(GETSTATIC, clsName, fieldName, "Ljava/lang/Class;");
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/NameMapping.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/NameMapping.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/NameMapping.java
new file mode 100644
index 0000000..70d74f7
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/NameMapping.java
@@ -0,0 +1,114 @@
+/***
+ * 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.apache.tapestry5.internal.plastic.asm.optimizer;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.tapestry5.internal.plastic.asm.Type;
+
+/**
+ * A MAPPING from names to names, used to rename classes, fields and methods.
+ *
+ * @author Eric Bruneton
+ */
+public class NameMapping {
+
+ public final Properties mapping;
+
+ public final Set<Object> unused;
+
+ public NameMapping(final String file) throws IOException {
+ mapping = new Properties();
+ InputStream is = null;
+ try {
+ is = new BufferedInputStream(new FileInputStream(file));
+ mapping.load(is);
+ unused = new HashSet<Object>(mapping.keySet());
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+
+ public String map(final String name) {
+ String s = (String) mapping.get(name);
+ if (s == null) {
+ int p = name.indexOf('.');
+ if (p == -1) {
+ s = name;
+ } else {
+ int q = name.indexOf('(');
+ if (q == -1) {
+ s = name.substring(p + 1);
+ } else {
+ s = name.substring(p + 1, q);
+ }
+ }
+ } else {
+ unused.remove(name);
+ }
+ return s;
+ }
+
+ public String fix(final String desc) {
+ if (desc.startsWith("(")) {
+ Type[] arguments = Type.getArgumentTypes(desc);
+ Type result = Type.getReturnType(desc);
+ for (int i = 0; i < arguments.length; ++i) {
+ arguments[i] = fix(arguments[i]);
+ }
+ result = fix(result);
+ return Type.getMethodDescriptor(result, arguments);
+ } else {
+ return fix(Type.getType(desc)).getDescriptor();
+ }
+ }
+
+ private Type fix(final Type t) {
+ if (t.getSort() == Type.OBJECT) {
+ return Type.getObjectType(map(t.getInternalName()));
+ } else if (t.getSort() == Type.ARRAY) {
+ String s = fix(t.getElementType()).getDescriptor();
+ for (int i = 0; i < t.getDimensions(); ++i) {
+ s = '[' + s;
+ }
+ return Type.getType(s);
+ } else {
+ return t;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/Shrinker.java
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/Shrinker.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/Shrinker.java
new file mode 100644
index 0000000..e20cf5c
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/Shrinker.java
@@ -0,0 +1,283 @@
+/***
+ * 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.apache.tapestry5.internal.plastic.asm.optimizer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.tapestry5.internal.plastic.asm.ClassReader;
+import org.apache.tapestry5.internal.plastic.asm.ClassWriter;
+import org.apache.tapestry5.internal.plastic.asm.Handle;
+import org.apache.tapestry5.internal.plastic.asm.Type;
+import org.apache.tapestry5.internal.plastic.asm.commons.Remapper;
+import org.apache.tapestry5.internal.plastic.asm.commons.SimpleRemapper;
+
+/**
+ * A class file shrinker utility.
+ *
+ * @author Eric Bruneton
+ * @author Eugene Kuleshov
+ */
+public class Shrinker {
+
+ static final HashMap<String, String> MAPPING = new HashMap<String, String>();
+
+ public static void main(final String[] args) throws IOException {
+ Properties properties = new Properties();
+ int n = args.length - 1;
+ for (int i = 0; i < n - 1; ++i) {
+ properties.load(new FileInputStream(args[i]));
+ }
+
+ for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+ MAPPING.put((String) entry.getKey(), (String) entry.getValue());
+ }
+
+ final Set<String> unused = new HashSet<String>(MAPPING.keySet());
+
+ File f = new File(args[n - 1]);
+ File d = new File(args[n]);
+
+ optimize(f, d, new SimpleRemapper(MAPPING) {
+ @Override
+ public String map(String key) {
+ String s = super.map(key);
+ if (s != null) {
+ unused.remove(key);
+ }
+ return s;
+ }
+ });
+
+ Iterator<String> i = unused.iterator();
+ while (i.hasNext()) {
+ String s = i.next();
+ if (!s.endsWith("/remove")) {
+ System.out.println("INFO: unused mapping " + s);
+ }
+ }
+ }
+
+ static void optimize(final File f, final File d, final Remapper remapper)
+ throws IOException {
+ if (f.isDirectory()) {
+ File[] files = f.listFiles();
+ for (int i = 0; i < files.length; ++i) {
+ optimize(files[i], d, remapper);
+ }
+ } else if (f.getName().endsWith(".class")) {
+ ConstantPool cp = new ConstantPool();
+ ClassReader cr = new ClassReader(new FileInputStream(f));
+ ClassWriter cw = new ClassWriter(0);
+ ClassConstantsCollector ccc = new ClassConstantsCollector(cw, cp);
+ ClassOptimizer co = new ClassOptimizer(ccc, remapper);
+ cr.accept(co, ClassReader.SKIP_DEBUG);
+
+ Set<Constant> constants = new TreeSet<Constant>(
+ new ConstantComparator());
+ constants.addAll(cp.values());
+
+ cr = new ClassReader(cw.toByteArray());
+ cw = new ClassWriter(0);
+ Iterator<Constant> i = constants.iterator();
+ while (i.hasNext()) {
+ Constant c = i.next();
+ c.write(cw);
+ }
+ cr.accept(cw, ClassReader.SKIP_DEBUG);
+
+ if (MAPPING.get(cr.getClassName() + "/remove") != null) {
+ return;
+ }
+ String n = remapper.mapType(cr.getClassName());
+ File g = new File(d, n + ".class");
+ if (!g.exists() || g.lastModified() < f.lastModified()) {
+ if (!g.getParentFile().exists() && !g.getParentFile().mkdirs()) {
+ throw new IOException("Cannot create directory "
+ + g.getParentFile());
+ }
+ OutputStream os = new FileOutputStream(g);
+ try {
+ os.write(cw.toByteArray());
+ } finally {
+ os.close();
+ }
+ }
+ }
+ }
+
+ static class ConstantComparator implements Comparator<Constant> {
+
+ public int compare(final Constant c1, final Constant c2) {
+ int d = getSort(c1) - getSort(c2);
+ if (d == 0) {
+ switch (c1.type) {
+ case 'I':
+ return new Integer(c1.intVal).compareTo(new Integer(
+ c2.intVal));
+ case 'J':
+ return new Long(c1.longVal).compareTo(new Long(c2.longVal));
+ case 'F':
+ return new Float(c1.floatVal).compareTo(new Float(
+ c2.floatVal));
+ case 'D':
+ return new Double(c1.doubleVal).compareTo(new Double(
+ c2.doubleVal));
+ case 's':
+ case 'S':
+ case 'C':
+ case 't':
+ return c1.strVal1.compareTo(c2.strVal1);
+ case 'T':
+ d = c1.strVal1.compareTo(c2.strVal1);
+ if (d == 0) {
+ d = c1.strVal2.compareTo(c2.strVal2);
+ }
+ break;
+ case 'y':
+ d = c1.strVal1.compareTo(c2.strVal1);
+ if (d == 0) {
+ d = c1.strVal2.compareTo(c2.strVal2);
+ if (d == 0) {
+ Handle bsm1 = (Handle) c1.objVal3;
+ Handle bsm2 = (Handle) c2.objVal3;
+ d = compareHandle(bsm1, bsm2);
+ if (d == 0) {
+ d = compareObjects(c1.objVals, c2.objVals);
+ }
+ }
+ }
+ break;
+
+ default:
+ d = c1.strVal1.compareTo(c2.strVal1);
+ if (d == 0) {
+ d = c1.strVal2.compareTo(c2.strVal2);
+ if (d == 0) {
+ d = ((String) c1.objVal3)
+ .compareTo((String) c2.objVal3);
+ }
+ }
+ }
+ }
+ return d;
+ }
+
+ private static int compareHandle(Handle h1, Handle h2) {
+ int d = h1.getTag() - h2.getTag();
+ if (d == 0) {
+ d = h1.getOwner().compareTo(h2.getOwner());
+ if (d == 0) {
+ d = h1.getName().compareTo(h2.getName());
+ if (d == 0) {
+ d = h1.getDesc().compareTo(h2.getDesc());
+ }
+ }
+ }
+ return d;
+ }
+
+ private static int compareType(Type mtype1, Type mtype2) {
+ return mtype1.getDescriptor().compareTo(mtype2.getDescriptor());
+ }
+
+ private static int compareObjects(Object[] objVals1, Object[] objVals2) {
+ int length = objVals1.length;
+ int d = length - objVals2.length;
+ if (d == 0) {
+ for (int i = 0; i < length; i++) {
+ Object objVal1 = objVals1[i];
+ Object objVal2 = objVals2[i];
+ d = objVal1.getClass().getName()
+ .compareTo(objVal2.getClass().getName());
+ if (d == 0) {
+ if (objVal1 instanceof Type) {
+ d = compareType((Type) objVal1, (Type) objVal2);
+ } else if (objVal1 instanceof Handle) {
+ d = compareHandle((Handle) objVal1,
+ (Handle) objVal2);
+ } else {
+ d = ((Comparable) objVal1).compareTo(objVal2);
+ }
+ }
+
+ if (d != 0) {
+ return d;
+ }
+ }
+ }
+ return 0;
+ }
+
+ private static int getSort(final Constant c) {
+ switch (c.type) {
+ case 'I':
+ return 0;
+ case 'J':
+ return 1;
+ case 'F':
+ return 2;
+ case 'D':
+ return 3;
+ case 's':
+ return 4;
+ case 'S':
+ return 5;
+ case 'C':
+ return 6;
+ case 'T':
+ return 7;
+ case 'G':
+ return 8;
+ case 'M':
+ return 9;
+ case 'N':
+ return 10;
+ case 'y':
+ return 11;
+ case 't':
+ return 12;
+ default:
+ return 100 + c.type - 'h';
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/jdk1.2.2_017.txt.gz
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/jdk1.2.2_017.txt.gz b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/jdk1.2.2_017.txt.gz
new file mode 100644
index 0000000..39cdf9d
Binary files /dev/null and b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/jdk1.2.2_017.txt.gz differ
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/jdk1.3.1_19.txt.gz
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/jdk1.3.1_19.txt.gz b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/jdk1.3.1_19.txt.gz
new file mode 100644
index 0000000..a3c7aa6
Binary files /dev/null and b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/jdk1.3.1_19.txt.gz differ
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/a0ac605d/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/shrink-annotations.properties
----------------------------------------------------------------------
diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/shrink-annotations.properties b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/shrink-annotations.properties
new file mode 100644
index 0000000..03fec2e
--- /dev/null
+++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/optimizer/shrink-annotations.properties
@@ -0,0 +1,53 @@
+###############################################################################
+#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.
+###############################################################################
+
+# class mappings
+
+org/objectweb/asm/AnnotationWriter/remove=true
+
+# field mappings
+
+org/objectweb/asm/ClassWriter.anns=-
+org/objectweb/asm/ClassWriter.ianns=-
+
+org/objectweb/asm/FieldWriter.anns=-
+org/objectweb/asm/FieldWriter.ianns=-
+
+org/objectweb/asm/MethodWriter.annd=-
+org/objectweb/asm/MethodWriter.anns=-
+org/objectweb/asm/MethodWriter.ianns=-
+org/objectweb/asm/MethodWriter.panns=-
+org/objectweb/asm/MethodWriter.ipanns=-
+
+# method mappings
+
+org/objectweb/asm/ClassReader.readAnnotationValue(I[CLjava/lang/String;Lorg/objectweb/asm/AnnotationVisitor;)I=-
+org/objectweb/asm/ClassReader.readAnnotationValues(I[CZLorg/objectweb/asm/AnnotationVisitor;)I=-
+org/objectweb/asm/ClassReader.readParameterAnnotations(I[CZLorg/objectweb/asm/MethodVisitor;)V=-