http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SerialVersionUIDAdder.java ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SerialVersionUIDAdder.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SerialVersionUIDAdder.java old mode 100644 new mode 100755 index 1f9b7cb..fed9697 --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SerialVersionUIDAdder.java +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SerialVersionUIDAdder.java @@ -1,32 +1,30 @@ -/*** - * 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. - */ +// 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.commons; import java.io.ByteArrayOutputStream; @@ -34,511 +32,459 @@ import java.io.DataOutput; import java.io.DataOutputStream; import java.io.IOException; import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; - +import java.util.Comparator; 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 {@link ClassVisitor} that adds a serial version unique identifier to a - * class if missing. Here is typical usage of this class: - * - * <pre> - * ClassWriter cw = new ClassWriter(...); - * ClassVisitor sv = new SerialVersionUIDAdder(cw); - * ClassVisitor ca = new MyClassAdapter(sv); - * new ClassReader(orginalClass).accept(ca, false); - * </pre> - * - * The SVUID algorithm can be found <a href= - * "http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html" - * >http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html</a>: - * + * A {@link ClassVisitor} that adds a serial version unique identifier to a class if missing. A + * typical usage of this class is: + * * <pre> - * The serialVersionUID is computed using the signature of a stream of bytes - * that reflect the class definition. The National Institute of Standards and - * Technology (NIST) Secure Hash Algorithm (SHA-1) is used to compute a - * signature for the stream. The first two 32-bit quantities are used to form a - * 64-bit hash. A java.lang.DataOutputStream is used to convert primitive data - * types to a sequence of bytes. The values input to the stream are defined by - * the Java Virtual Machine (VM) specification for classes. - * - * The sequence of items in the stream is as follows: - * - * 1. The class name written using UTF encoding. - * 2. The class modifiers written as a 32-bit integer. - * 3. The name of each interface sorted by name written using UTF encoding. - * 4. For each field of the class sorted by field name (except private static - * and private transient fields): - * 1. The name of the field in UTF encoding. - * 2. The modifiers of the field written as a 32-bit integer. - * 3. The descriptor of the field in UTF encoding - * 5. If a class initializer exists, write out the following: - * 1. The name of the method, <clinit>, in UTF encoding. - * 2. The modifier of the method, java.lang.reflect.Modifier.STATIC, - * written as a 32-bit integer. - * 3. The descriptor of the method, ()V, in UTF encoding. - * 6. For each non-private constructor sorted by method name and signature: - * 1. The name of the method, <init>, in UTF encoding. - * 2. The modifiers of the method written as a 32-bit integer. - * 3. The descriptor of the method in UTF encoding. - * 7. For each non-private method sorted by method name and signature: - * 1. The name of the method in UTF encoding. - * 2. The modifiers of the method written as a 32-bit integer. - * 3. The descriptor of the method in UTF encoding. - * 8. The SHA-1 algorithm is executed on the stream of bytes produced by - * DataOutputStream and produces five 32-bit values sha[0..4]. - * - * 9. The hash value is assembled from the first and second 32-bit values of - * the SHA-1 message digest. If the result of the message digest, the five - * 32-bit words H0 H1 H2 H3 H4, is in an array of five int values named - * sha, the hash value would be computed as follows: - * - * long hash = ((sha[0] >>> 24) & 0xFF) | - * ((sha[0] >>> 16) & 0xFF) << 8 | - * ((sha[0] >>> 8) & 0xFF) << 16 | - * ((sha[0] >>> 0) & 0xFF) << 24 | - * ((sha[1] >>> 24) & 0xFF) << 32 | - * ((sha[1] >>> 16) & 0xFF) << 40 | - * ((sha[1] >>> 8) & 0xFF) << 48 | - * ((sha[1] >>> 0) & 0xFF) << 56; + * ClassWriter classWriter = new ClassWriter(...); + * ClassVisitor svuidAdder = new SerialVersionUIDAdder(classWriter); + * ClassVisitor classVisitor = new MyClassAdapter(svuidAdder); + * new ClassReader(orginalClass).accept(classVisitor, 0); * </pre> - * + * + * <p>The SVUID algorithm can be found at <a href= + * "https://docs.oracle.com/javase/10/docs/specs/serialization/class.html#stream-unique-identifiers" + * >https://docs.oracle.com/javase/10/docs/specs/serialization/class.html#stream-unique-identifiers</a>: + * + * <p>The serialVersionUID is computed using the signature of a stream of bytes that reflect the + * class definition. The National Institute of Standards and Technology (NIST) Secure Hash Algorithm + * (SHA-1) is used to compute a signature for the stream. The first two 32-bit quantities are used + * to form a 64-bit hash. A java.lang.DataOutputStream is used to convert primitive data types to a + * sequence of bytes. The values input to the stream are defined by the Java Virtual Machine (VM) + * specification for classes. + * + * <p>The sequence of items in the stream is as follows: + * + * <ol> + * <li>The class name written using UTF encoding. + * <li>The class modifiers written as a 32-bit integer. + * <li>The name of each interface sorted by name written using UTF encoding. + * <li>For each field of the class sorted by field name (except private static and private + * transient fields): + * <ol> + * <li>The name of the field in UTF encoding. + * <li>The modifiers of the field written as a 32-bit integer. + * <li>The descriptor of the field in UTF encoding + * </ol> + * <li>If a class initializer exists, write out the following: + * <ol> + * <li>The name of the method, <clinit>, in UTF encoding. + * <li>The modifier of the method, STATIC, written as a 32-bit integer. + * <li>The descriptor of the method, ()V, in UTF encoding. + * </ol> + * <li>For each non-private constructor sorted by method name and signature: + * <ol> + * <li>The name of the method, <init>, in UTF encoding. + * <li>The modifiers of the method written as a 32-bit integer. + * <li>The descriptor of the method in UTF encoding. + * </ol> + * <li>For each non-private method sorted by method name and signature: + * <ol> + * <li>The name of the method in UTF encoding. + * <li>The modifiers of the method written as a 32-bit integer. + * <li>The descriptor of the method in UTF encoding. + * </ol> + * <li>The SHA-1 algorithm is executed on the stream of bytes produced by DataOutputStream and + * produces five 32-bit values sha[0..4]. + * <li>The hash value is assembled from the first and second 32-bit values of the SHA-1 message + * digest. If the result of the message digest, the five 32-bit words H0 H1 H2 H3 H4, is in an + * array of five int values named sha, the hash value would be computed as follows: long hash + * = ((sha[0] >>> 24) & 0xFF) | ((sha[0] >>> 16) & 0xFF) << 8 + * | ((sha[0] >>> 8) & 0xFF) << 16 | ((sha[0] >>> 0) & 0xFF) + * << 24 | ((sha[1] >>> 24) & 0xFF) << 32 | ((sha[1] >>> 16) + * & 0xFF) << 40 | ((sha[1] >>> 8) & 0xFF) << 48 | ((sha[1] + * >>> 0) & 0xFF) << 56; + * </ol> + * * @author Rajendra Inamdar, Vishal Vishnoi */ +// DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility). public class SerialVersionUIDAdder extends ClassVisitor { - /** - * Flag that indicates if we need to compute SVUID. - */ - private boolean computeSVUID; - - /** - * Set to true if the class already has SVUID. - */ - private boolean hasSVUID; - - /** - * Classes access flags. - */ - private int access; - - /** - * Internal name of the class - */ - private String name; - - /** - * Interfaces implemented by the class. - */ - private String[] interfaces; - - /** - * Collection of fields. (except private static and private transient - * fields) - */ - private Collection<Item> svuidFields; - - /** - * Set to true if the class has static initializer. - */ - private boolean hasStaticInitializer; - - /** - * Collection of non-private constructors. - */ - private Collection<Item> svuidConstructors; - - /** - * Collection of non-private methods. - */ - private Collection<Item> svuidMethods; - - /** - * Creates a new {@link SerialVersionUIDAdder}. <i>Subclasses must not use - * this constructor</i>. Instead, they must use the - * {@link #SerialVersionUIDAdder(int, ClassVisitor)} version. - * - * @param cv - * a {@link ClassVisitor} to which this visitor will delegate - * calls. - * @throws IllegalStateException - * If a subclass calls this constructor. - */ - public SerialVersionUIDAdder(final ClassVisitor cv) { - this(Opcodes.ASM6, cv); - if (getClass() != SerialVersionUIDAdder.class) { - throw new IllegalStateException(); - } - } + /** The JVM name of static initializer methods. */ + private static final String CLINIT = "<clinit>"; - /** - * Creates a new {@link SerialVersionUIDAdder}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. - * @param cv - * a {@link ClassVisitor} to which this visitor will delegate - * calls. - */ - protected SerialVersionUIDAdder(final int api, final ClassVisitor cv) { - super(api, cv); - svuidFields = new ArrayList<Item>(); - svuidConstructors = new ArrayList<Item>(); - svuidMethods = new ArrayList<Item>(); - } + /** A flag that indicates if we need to compute SVUID. */ + private boolean computeSvuid; - // ------------------------------------------------------------------------ - // Overridden methods - // ------------------------------------------------------------------------ - - /* - * Visit class header and get class name, access , and interfaces - * information (step 1,2, and 3) for SVUID computation. - */ - @Override - public void visit(final int version, final int access, final String name, - final String signature, final String superName, - final String[] interfaces) { - computeSVUID = (access & Opcodes.ACC_ENUM) == 0; - - if (computeSVUID) { - this.name = name; - this.access = access; - this.interfaces = new String[interfaces.length]; - System.arraycopy(interfaces, 0, this.interfaces, 0, - interfaces.length); - } + /** Whether the class already has a SVUID. */ + private boolean hasSvuid; - super.visit(version, access, name, signature, superName, interfaces); - } + /** The class access flags. */ + private int access; - /* - * Visit the methods and get constructor and method information (step 5 and - * 7). Also determine if there is a class initializer (step 6). - */ - @Override - public MethodVisitor visitMethod(final int access, final String name, - final String desc, final String signature, final String[] exceptions) { - if (computeSVUID) { - if ("<clinit>".equals(name)) { - hasStaticInitializer = true; - } - /* - * Remembers non private constructors and methods for SVUID - * computation For constructor and method modifiers, only the - * ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, - * ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and ACC_STRICT flags - * are used. - */ - int mods = access - & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE - | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC - | Opcodes.ACC_FINAL | Opcodes.ACC_SYNCHRONIZED - | Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_STRICT); - - // all non private methods - if ((access & Opcodes.ACC_PRIVATE) == 0) { - if ("<init>".equals(name)) { - svuidConstructors.add(new Item(name, mods, desc)); - } else if (!"<clinit>".equals(name)) { - svuidMethods.add(new Item(name, mods, desc)); - } - } - } + /** The internal name of the class. */ + private String name; - return super.visitMethod(access, name, desc, signature, exceptions); - } + /** The interfaces implemented by the class. */ + private String[] interfaces; - /* - * Gets class field information for step 4 of the algorithm. Also determines - * if the class already has a SVUID. - */ - @Override - public FieldVisitor visitField(final int access, final String name, - final String desc, final String signature, final Object value) { - if (computeSVUID) { - if ("serialVersionUID".equals(name)) { - // since the class already has SVUID, we won't be computing it. - computeSVUID = false; - hasSVUID = true; - } - /* - * Remember field for SVUID computation For field modifiers, only - * the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, - * ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT flags are used when - * computing serialVersionUID values. - */ - if ((access & Opcodes.ACC_PRIVATE) == 0 - || (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) { - int mods = access - & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE - | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC - | Opcodes.ACC_FINAL | Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT); - svuidFields.add(new Item(name, mods, desc)); - } - } + /** The fields of the class that are needed to compute the SVUID. */ + private Collection<Item> svuidFields; - return super.visitField(access, name, desc, signature, value); - } + /** Whether the class has a static initializer. */ + private boolean hasStaticInitializer; - /** - * Handle a bizarre special case. Nested classes (static classes declared - * inside another class) that are protected have their access bit set to - * public in their class files to deal with some odd reflection situation. - * Our SVUID computation must do as the JVM does and ignore access bits in - * the class file in favor of the access bits InnerClass attribute. - */ - @Override - public void visitInnerClass(final String aname, final String outerName, - final String innerName, final int attr_access) { - if ((name != null) && name.equals(aname)) { - this.access = attr_access; - } - super.visitInnerClass(aname, outerName, innerName, attr_access); - } + /** The constructors of the class that are needed to compute the SVUID. */ + private Collection<Item> svuidConstructors; - /* - * Add the SVUID if class doesn't have one - */ - @Override - public void visitEnd() { - // compute SVUID and add it to the class - if (computeSVUID && !hasSVUID) { - try { - addSVUID(computeSVUID()); - } catch (Throwable e) { - throw new RuntimeException("Error while computing SVUID for " - + name, e); - } - } + /** The methods of the class that are needed to compute the SVUID. */ + private Collection<Item> svuidMethods; - super.visitEnd(); + /** + * Constructs a new {@link SerialVersionUIDAdder}. <i>Subclasses must not use this + * constructor</i>. Instead, they must use the {@link #SerialVersionUIDAdder(int, ClassVisitor)} + * version. + * + * @param classVisitor a {@link ClassVisitor} to which this visitor will delegate calls. + * @throws IllegalStateException If a subclass calls this constructor. + */ + public SerialVersionUIDAdder(final ClassVisitor classVisitor) { + this(Opcodes.ASM7, classVisitor); + if (getClass() != SerialVersionUIDAdder.class) { + throw new IllegalStateException(); } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - /** - * Returns true if the class already has a SVUID field. The result of this - * method is only valid when visitEnd is or has been called. - * - * @return true if the class already has a SVUID field. - */ - public boolean hasSVUID() { - return hasSVUID; + } + + /** + * Constructs a new {@link SerialVersionUIDAdder}. + * + * @param api the ASM API version implemented by this visitor. Must be one of {@link + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. + * @param classVisitor a {@link ClassVisitor} to which this visitor will delegate calls. + */ + protected SerialVersionUIDAdder(final int api, final ClassVisitor classVisitor) { + super(api, classVisitor); + } + + // ----------------------------------------------------------------------------------------------- + // Overridden methods + // ----------------------------------------------------------------------------------------------- + + @Override + public void visit( + final int version, + final int access, + final String name, + final String signature, + final String superName, + final String[] interfaces) { + // Get the class name, access flags, and interfaces information (step 1, 2 and 3) for SVUID + // computation. + computeSvuid = (access & Opcodes.ACC_ENUM) == 0; + + if (computeSvuid) { + this.name = name; + this.access = access; + this.interfaces = new String[interfaces.length]; + this.svuidFields = new ArrayList<Item>(); + this.svuidConstructors = new ArrayList<Item>(); + this.svuidMethods = new ArrayList<Item>(); + System.arraycopy(interfaces, 0, this.interfaces, 0, interfaces.length); } - protected void addSVUID(long svuid) { - FieldVisitor fv = super.visitField(Opcodes.ACC_FINAL - + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, svuid); - if (fv != null) { - fv.visitEnd(); + super.visit(version, access, name, signature, superName, interfaces); + } + + @Override + public MethodVisitor visitMethod( + final int access, + final String name, + final String descriptor, + final String signature, + final String[] exceptions) { + // Get constructor and method information (step 5 and 7). Also determine if there is a class + // initializer (step 6). + if (computeSvuid) { + if (CLINIT.equals(name)) { + hasStaticInitializer = true; + } + // Collect the non private constructors and methods. Only the ACC_PUBLIC, ACC_PRIVATE, + // ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and + // ACC_STRICT flags are used. + int mods = + access + & (Opcodes.ACC_PUBLIC + | Opcodes.ACC_PRIVATE + | Opcodes.ACC_PROTECTED + | Opcodes.ACC_STATIC + | Opcodes.ACC_FINAL + | Opcodes.ACC_SYNCHRONIZED + | Opcodes.ACC_NATIVE + | Opcodes.ACC_ABSTRACT + | Opcodes.ACC_STRICT); + + if ((access & Opcodes.ACC_PRIVATE) == 0) { + if ("<init>".equals(name)) { + svuidConstructors.add(new Item(name, mods, descriptor)); + } else if (!CLINIT.equals(name)) { + svuidMethods.add(new Item(name, mods, descriptor)); } + } } - /** - * Computes and returns the value of SVUID. - * - * @return Returns the serial version UID - * @throws IOException - * if an I/O error occurs - */ - protected long computeSVUID() throws IOException { - ByteArrayOutputStream bos; - DataOutputStream dos = null; - long svuid = 0; - - try { - bos = new ByteArrayOutputStream(); - dos = new DataOutputStream(bos); - - /* - * 1. The class name written using UTF encoding. - */ - dos.writeUTF(name.replace('/', '.')); - - /* - * 2. The class modifiers written as a 32-bit integer. - */ - int access = this.access; - if ((access & Opcodes.ACC_INTERFACE) != 0) { - access = (svuidMethods.size() > 0) ? (access | Opcodes.ACC_ABSTRACT) - : (access & ~Opcodes.ACC_ABSTRACT); - } - dos.writeInt(access - & (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL - | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT)); - - /* - * 3. The name of each interface sorted by name written using UTF - * encoding. - */ - Arrays.sort(interfaces); - for (int i = 0; i < interfaces.length; i++) { - dos.writeUTF(interfaces[i].replace('/', '.')); - } - - /* - * 4. For each field of the class sorted by field name (except - * private static and private transient fields): - * - * 1. The name of the field in UTF encoding. 2. The modifiers of the - * field written as a 32-bit integer. 3. The descriptor of the field - * in UTF encoding - * - * Note that field signatures are not dot separated. Method and - * constructor signatures are dot separated. Go figure... - */ - writeItems(svuidFields, dos, false); - - /* - * 5. If a class initializer exists, write out the following: 1. The - * name of the method, <clinit>, in UTF encoding. 2. The modifier of - * the method, java.lang.reflect.Modifier.STATIC, written as a - * 32-bit integer. 3. The descriptor of the method, ()V, in UTF - * encoding. - */ - if (hasStaticInitializer) { - dos.writeUTF("<clinit>"); - dos.writeInt(Opcodes.ACC_STATIC); - dos.writeUTF("()V"); - } // if.. - - /* - * 6. For each non-private constructor sorted by method name and - * signature: 1. The name of the method, <init>, in UTF encoding. 2. - * The modifiers of the method written as a 32-bit integer. 3. The - * descriptor of the method in UTF encoding. - */ - writeItems(svuidConstructors, dos, true); - - /* - * 7. For each non-private method sorted by method name and - * signature: 1. The name of the method in UTF encoding. 2. The - * modifiers of the method written as a 32-bit integer. 3. The - * descriptor of the method in UTF encoding. - */ - writeItems(svuidMethods, dos, true); - - dos.flush(); - - /* - * 8. The SHA-1 algorithm is executed on the stream of bytes - * produced by DataOutputStream and produces five 32-bit values - * sha[0..4]. - */ - byte[] hashBytes = computeSHAdigest(bos.toByteArray()); - - /* - * 9. The hash value is assembled from the first and second 32-bit - * values of the SHA-1 message digest. If the result of the message - * digest, the five 32-bit words H0 H1 H2 H3 H4, is in an array of - * five int values named sha, the hash value would be computed as - * follows: - * - * long hash = ((sha[0] >>> 24) & 0xFF) | ((sha[0] >>> 16) & 0xFF) - * << 8 | ((sha[0] >>> 8) & 0xFF) << 16 | ((sha[0] >>> 0) & 0xFF) << - * 24 | ((sha[1] >>> 24) & 0xFF) << 32 | ((sha[1] >>> 16) & 0xFF) << - * 40 | ((sha[1] >>> 8) & 0xFF) << 48 | ((sha[1] >>> 0) & 0xFF) << - * 56; - */ - for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) { - svuid = (svuid << 8) | (hashBytes[i] & 0xFF); - } - } finally { - // close the stream (if open) - if (dos != null) { - dos.close(); - } - } - - return svuid; + return super.visitMethod(access, name, descriptor, signature, exceptions); + } + + @Override + public FieldVisitor visitField( + final int access, + final String name, + final String desc, + final String signature, + final Object value) { + // Get the class field information for step 4 of the algorithm. Also determine if the class + // already has a SVUID. + if (computeSvuid) { + if ("serialVersionUID".equals(name)) { + // Since the class already has SVUID, we won't be computing it. + computeSvuid = false; + hasSvuid = true; + } + // Collect the non private fields. Only the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, + // ACC_STATIC, ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT flags are used when computing + // serialVersionUID values. + if ((access & Opcodes.ACC_PRIVATE) == 0 + || (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) { + int mods = + access + & (Opcodes.ACC_PUBLIC + | Opcodes.ACC_PRIVATE + | Opcodes.ACC_PROTECTED + | Opcodes.ACC_STATIC + | Opcodes.ACC_FINAL + | Opcodes.ACC_VOLATILE + | Opcodes.ACC_TRANSIENT); + svuidFields.add(new Item(name, mods, desc)); + } } - /** - * Returns the SHA-1 message digest of the given value. - * - * @param value - * the value whose SHA message digest must be computed. - * @return the SHA-1 message digest of the given value. - */ - protected byte[] computeSHAdigest(final byte[] value) { - try { - return MessageDigest.getInstance("SHA").digest(value); - } catch (Exception e) { - throw new UnsupportedOperationException(e.toString()); - } + return super.visitField(access, name, desc, signature, value); + } + + @Override + public void visitInnerClass( + final String innerClassName, + final String outerName, + final String innerName, + final int innerClassAccess) { + // Handles a bizarre special case. Nested classes (static classes declared inside another class) + // that are protected have their access bit set to public in their class files to deal with some + // odd reflection situation. Our SVUID computation must do as the JVM does and ignore access + // bits in the class file in favor of the access bits of the InnerClass attribute. + if ((name != null) && name.equals(innerClassName)) { + this.access = innerClassAccess; } - - /** - * Sorts the items in the collection and writes it to the data output stream - * - * @param itemCollection - * collection of items - * @param dos - * a <code>DataOutputStream</code> value - * @param dotted - * a <code>boolean</code> value - * @exception IOException - * if an error occurs - */ - private static void writeItems(final Collection<Item> itemCollection, - final DataOutput dos, final boolean dotted) throws IOException { - int size = itemCollection.size(); - Item[] items = itemCollection.toArray(new Item[size]); - Arrays.sort(items); - for (int i = 0; i < size; i++) { - dos.writeUTF(items[i].name); - dos.writeInt(items[i].access); - dos.writeUTF(dotted ? items[i].desc.replace('/', '.') - : items[i].desc); - } + super.visitInnerClass(innerClassName, outerName, innerName, innerClassAccess); + } + + @Override + public void visitEnd() { + // Add the SVUID field to the class if it doesn't have one. + if (computeSvuid && !hasSvuid) { + try { + addSVUID(computeSVUID()); + } catch (IOException e) { + throw new IllegalStateException("Error while computing SVUID for " + name, e); + } } - // ------------------------------------------------------------------------ - // Inner classes - // ------------------------------------------------------------------------ - - private static class Item implements Comparable<Item> { + super.visitEnd(); + } + + // ----------------------------------------------------------------------------------------------- + // Utility methods + // ----------------------------------------------------------------------------------------------- + + /** + * Returns true if the class already has a SVUID field. The result of this method is only valid + * when visitEnd has been called. + * + * @return true if the class already has a SVUID field. + */ + // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility). + public boolean hasSVUID() { + return hasSvuid; + } + + /** + * Adds a final static serialVersionUID field to the class, with the given value. + * + * @param svuid the serialVersionUID field value. + */ + // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility). + protected void addSVUID(final long svuid) { + FieldVisitor fieldVisitor = + super.visitField( + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "serialVersionUID", "J", null, svuid); + if (fieldVisitor != null) { + fieldVisitor.visitEnd(); + } + } + + /** + * Computes and returns the value of SVUID. + * + * @return the serial version UID. + * @throws IOException if an I/O error occurs. + */ + // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility). + protected long computeSVUID() throws IOException { + ByteArrayOutputStream byteArrayOutputStream = null; + DataOutputStream dataOutputStream = null; + long svuid = 0; + + try { + byteArrayOutputStream = new ByteArrayOutputStream(); + dataOutputStream = new DataOutputStream(byteArrayOutputStream); + + // 1. The class name written using UTF encoding. + dataOutputStream.writeUTF(name.replace('/', '.')); + + // 2. The class modifiers written as a 32-bit integer. + int mods = access; + if ((mods & Opcodes.ACC_INTERFACE) != 0) { + mods = + svuidMethods.isEmpty() ? (mods & ~Opcodes.ACC_ABSTRACT) : (mods | Opcodes.ACC_ABSTRACT); + } + dataOutputStream.writeInt( + mods + & (Opcodes.ACC_PUBLIC + | Opcodes.ACC_FINAL + | Opcodes.ACC_INTERFACE + | Opcodes.ACC_ABSTRACT)); + + // 3. The name of each interface sorted by name written using UTF encoding. + Arrays.sort(interfaces); + for (String interfaceName : interfaces) { + dataOutputStream.writeUTF(interfaceName.replace('/', '.')); + } + + // 4. For each field of the class sorted by field name (except private static and private + // transient fields): + // 1. The name of the field in UTF encoding. + // 2. The modifiers of the field written as a 32-bit integer. + // 3. The descriptor of the field in UTF encoding. + // Note that field signatures are not dot separated. Method and constructor signatures are dot + // separated. Go figure... + writeItems(svuidFields, dataOutputStream, false); + + // 5. If a class initializer exists, write out the following: + // 1. The name of the method, <clinit>, in UTF encoding. + // 2. The modifier of the method, ACC_STATIC, written as a 32-bit integer. + // 3. The descriptor of the method, ()V, in UTF encoding. + if (hasStaticInitializer) { + dataOutputStream.writeUTF(CLINIT); + dataOutputStream.writeInt(Opcodes.ACC_STATIC); + dataOutputStream.writeUTF("()V"); + } + + // 6. For each non-private constructor sorted by method name and signature: + // 1. The name of the method, <init>, in UTF encoding. + // 2. The modifiers of the method written as a 32-bit integer. + // 3. The descriptor of the method in UTF encoding. + writeItems(svuidConstructors, dataOutputStream, true); + + // 7. For each non-private method sorted by method name and signature: + // 1. The name of the method in UTF encoding. + // 2. The modifiers of the method written as a 32-bit integer. + // 3. The descriptor of the method in UTF encoding. + writeItems(svuidMethods, dataOutputStream, true); + + dataOutputStream.flush(); + + // 8. The SHA-1 algorithm is executed on the stream of bytes produced by DataOutputStream and + // produces five 32-bit values sha[0..4]. + byte[] hashBytes = computeSHAdigest(byteArrayOutputStream.toByteArray()); + + // 9. The hash value is assembled from the first and second 32-bit values of the SHA-1 message + // digest. If the result of the message digest, the five 32-bit words H0 H1 H2 H3 H4, is in an + // array of five int values named sha, the hash value would be computed as follows: + for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) { + svuid = (svuid << 8) | (hashBytes[i] & 0xFF); + } + } finally { + if (dataOutputStream != null) { + dataOutputStream.close(); + } + } - final String name; + return svuid; + } + + /** + * Returns the SHA-1 message digest of the given value. + * + * @param value the value whose SHA message digest must be computed. + * @return the SHA-1 message digest of the given value. + */ + // DontCheck(AbbreviationAsWordInName): can't be renamed (for backward binary compatibility). + protected byte[] computeSHAdigest(final byte[] value) { + try { + return MessageDigest.getInstance("SHA").digest(value); + } catch (NoSuchAlgorithmException e) { + throw new UnsupportedOperationException(e); + } + } + + /** + * Sorts the items in the collection and writes it to the given output stream. + * + * @param itemCollection a collection of items. + * @param dataOutputStream where the items must be written. + * @param dotted whether package names must use dots, instead of slashes. + * @exception IOException if an error occurs. + */ + private static void writeItems( + final Collection<Item> itemCollection, + final DataOutput dataOutputStream, + final boolean dotted) + throws IOException { + Item[] items = itemCollection.toArray(new Item[0]); + Arrays.sort( + items, + new Comparator<Item>() { + @Override + public int compare(final Item item1, final Item item2) { + int result = item1.name.compareTo(item2.name); + if (result == 0) { + result = item1.descriptor.compareTo(item2.descriptor); + } + return result; + } + }); + for (Item item : items) { + dataOutputStream.writeUTF(item.name); + dataOutputStream.writeInt(item.access); + dataOutputStream.writeUTF(dotted ? item.descriptor.replace('/', '.') : item.descriptor); + } + } - final int access; + // ----------------------------------------------------------------------------------------------- + // Inner classes + // ----------------------------------------------------------------------------------------------- - final String desc; + private static final class Item { - Item(final String name, final int access, final String desc) { - this.name = name; - this.access = access; - this.desc = desc; - } + final String name; + final int access; + final String descriptor; - public int compareTo(final Item other) { - int retVal = name.compareTo(other.name); - if (retVal == 0) { - retVal = desc.compareTo(other.desc); - } - return retVal; - } - - @Override - public boolean equals(final Object o) { - if (o instanceof Item) { - return compareTo((Item) o) == 0; - } - return false; - } - - @Override - public int hashCode() { - return (name + desc).hashCode(); - } + Item(final String name, final int access, final String descriptor) { + this.name = name; + this.access = access; + this.descriptor = descriptor; } + } }
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SignatureRemapper.java ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SignatureRemapper.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SignatureRemapper.java old mode 100644 new mode 100755 index b16e028..d5d29ff --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SignatureRemapper.java +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SignatureRemapper.java @@ -1,159 +1,174 @@ -/*** - * 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. - */ +// 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.commons; -import java.util.Stack; - +import java.util.ArrayList; import org.apache.tapestry5.internal.plastic.asm.Opcodes; import org.apache.tapestry5.internal.plastic.asm.signature.SignatureVisitor; /** - * A {@link SignatureVisitor} adapter for type mapping. - * + * A {@link SignatureVisitor} that remaps types with a {@link Remapper}. + * * @author Eugene Kuleshov */ public class SignatureRemapper extends SignatureVisitor { - private final SignatureVisitor v; - - private final Remapper remapper; - - private Stack<String> classNames = new Stack<String>(); - - public SignatureRemapper(final SignatureVisitor v, final Remapper remapper) { - this(Opcodes.ASM6, v, remapper); - } - - protected SignatureRemapper(final int api, final SignatureVisitor v, - final Remapper remapper) { - super(api); - this.v = v; - this.remapper = remapper; - } - - @Override - public void visitClassType(String name) { - classNames.push(name); - v.visitClassType(remapper.mapType(name)); - } - - @Override - public void visitInnerClassType(String name) { - String outerClassName = classNames.pop(); - String className = outerClassName + '$' + name; - classNames.push(className); - String remappedOuter = remapper.mapType(outerClassName) + '$'; - 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(); - classNames.pop(); - } + private final SignatureVisitor signatureVisitor; + + private final Remapper remapper; + + private ArrayList<String> classNames = new ArrayList<String>(); + + /** + * Constructs a new {@link SignatureRemapper}. <i>Subclasses must not use this constructor</i>. + * Instead, they must use the {@link #SignatureRemapper(int,SignatureVisitor,Remapper)} version. + * + * @param signatureVisitor the signature visitor this remapper must deleted to. + * @param remapper the remapper to use to remap the types in the visited signature. + */ + public SignatureRemapper(final SignatureVisitor signatureVisitor, final Remapper remapper) { + this(Opcodes.ASM7, signatureVisitor, remapper); + } + + /** + * Constructs a new {@link SignatureRemapper}. + * + * @param api the ASM API version supported by this remapper. Must be one of {@link + * org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM4}, {@link org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM5} or {@link + * org.apache.tapestry5.internal.plastic.asm.Opcodes#ASM6}. + * @param signatureVisitor the signature visitor this remapper must deleted to. + * @param remapper the remapper to use to remap the types in the visited signature. + */ + protected SignatureRemapper( + final int api, final SignatureVisitor signatureVisitor, final Remapper remapper) { + super(api); + this.signatureVisitor = signatureVisitor; + this.remapper = remapper; + } + + @Override + public void visitClassType(final String name) { + classNames.add(name); + signatureVisitor.visitClassType(remapper.mapType(name)); + } + + @Override + public void visitInnerClassType(final String name) { + String outerClassName = classNames.remove(classNames.size() - 1); + String className = outerClassName + '$' + name; + classNames.add(className); + String remappedOuter = remapper.mapType(outerClassName) + '$'; + String remappedName = remapper.mapType(className); + int index = + remappedName.startsWith(remappedOuter) + ? remappedOuter.length() + : remappedName.lastIndexOf('$') + 1; + signatureVisitor.visitInnerClassType(remappedName.substring(index)); + } + + @Override + public void visitFormalTypeParameter(final String name) { + signatureVisitor.visitFormalTypeParameter(name); + } + + @Override + public void visitTypeVariable(final String name) { + signatureVisitor.visitTypeVariable(name); + } + + @Override + public SignatureVisitor visitArrayType() { + signatureVisitor.visitArrayType(); + return this; + } + + @Override + public void visitBaseType(final char descriptor) { + signatureVisitor.visitBaseType(descriptor); + } + + @Override + public SignatureVisitor visitClassBound() { + signatureVisitor.visitClassBound(); + return this; + } + + @Override + public SignatureVisitor visitExceptionType() { + signatureVisitor.visitExceptionType(); + return this; + } + + @Override + public SignatureVisitor visitInterface() { + signatureVisitor.visitInterface(); + return this; + } + + @Override + public SignatureVisitor visitInterfaceBound() { + signatureVisitor.visitInterfaceBound(); + return this; + } + + @Override + public SignatureVisitor visitParameterType() { + signatureVisitor.visitParameterType(); + return this; + } + + @Override + public SignatureVisitor visitReturnType() { + signatureVisitor.visitReturnType(); + return this; + } + + @Override + public SignatureVisitor visitSuperclass() { + signatureVisitor.visitSuperclass(); + return this; + } + + @Override + public void visitTypeArgument() { + signatureVisitor.visitTypeArgument(); + } + + @Override + public SignatureVisitor visitTypeArgument(final char wildcard) { + signatureVisitor.visitTypeArgument(wildcard); + return this; + } + + @Override + public void visitEnd() { + signatureVisitor.visitEnd(); + classNames.remove(classNames.size() - 1); + } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SimpleRemapper.java ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SimpleRemapper.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SimpleRemapper.java old mode 100644 new mode 100755 index 68c7825..bd76a09 --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SimpleRemapper.java +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/SimpleRemapper.java @@ -1,32 +1,30 @@ -/*** - * 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. - */ +// 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.commons; @@ -40,36 +38,59 @@ import java.util.Map; */ public class SimpleRemapper extends Remapper { - private final Map<String, String> mapping; + private final Map<String, String> mapping; - public SimpleRemapper(Map<String, String> mapping) { - this.mapping = mapping; - } + /** + * Constructs a new {@link SimpleRemapper} with the given mapping. + * + * @param mapping a map specifying a remapping as follows: + * <ul> + * <li>for method names, the key is the owner, name and descriptor of the method (in the + * form <owner>.<name><descriptor>), and the value is the new method + * name. + * <li>for invokedynamic method names, the key is the name and descriptor of the method (in + * the form .<name><descriptor>), and the value is the new method name. + * <li>for field names, the key is the owner and name of the field (in the form + * <owner>.<name>), and the value is the new field name. + * <li>for internal names, the key is the old internal name, and the value is the new + * internal name. + * </ul> + */ + public SimpleRemapper(final Map<String, String> mapping) { + this.mapping = mapping; + } - public SimpleRemapper(String oldName, String newName) { - this.mapping = Collections.singletonMap(oldName, newName); - } + /** + * Constructs a new {@link SimpleRemapper} with the given mapping. + * + * @param oldName the key corresponding to a method, field or internal name (see {@link + * #SimpleRemapper(Map)} for the format of these keys). + * @param newName the new method, field or internal name. + */ + public SimpleRemapper(final String oldName, final 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 mapMethodName(final String owner, final String name, final String descriptor) { + String remappedName = map(owner + '.' + name + descriptor); + return remappedName == null ? name : remappedName; + } - @Override - public String mapInvokeDynamicMethodName(String name, String desc) { - String s = map('.' + name + desc); - return s == null ? name : s; - } + @Override + public String mapInvokeDynamicMethodName(final String name, final String descriptor) { + String remappedName = map('.' + name + descriptor); + return remappedName == null ? name : remappedName; + } - @Override - public String mapFieldName(String owner, String name, String desc) { - String s = map(owner + '.' + name); - return s == null ? name : s; - } + @Override + public String mapFieldName(final String owner, final String name, final String descriptor) { + String remappedName = map(owner + '.' + name); + return remappedName == null ? name : remappedName; + } - @Override - public String map(String key) { - return mapping.get(key); - } + @Override + public String map(final String key) { + return mapping.get(key); + } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/StaticInitMerger.java ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/StaticInitMerger.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/StaticInitMerger.java old mode 100644 new mode 100755 index 2bb33e5..ee0228d --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/StaticInitMerger.java +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/StaticInitMerger.java @@ -1,32 +1,30 @@ -/*** - * 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. - */ +// 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.commons; import org.apache.tapestry5.internal.plastic.asm.ClassVisitor; @@ -34,64 +32,93 @@ import org.apache.tapestry5.internal.plastic.asm.MethodVisitor; import org.apache.tapestry5.internal.plastic.asm.Opcodes; /** - * A {@link ClassVisitor} that merges clinit methods into a single one. - * + * A {@link ClassVisitor} that merges <clinit> methods into a single one. All the existing + * <clinit> methods are renamed, and a new one is created, which calls all the renamed + * methods. + * * @author Eric Bruneton */ public class StaticInitMerger extends ClassVisitor { - private String name; + /** The internal name of the visited class. */ + private String owner; - private MethodVisitor clinit; + /** The prefix to use to rename the existing <clinit> methods. */ + private final String renamedClinitMethodPrefix; - private final String prefix; + /** The number of <clinit> methods visited so far. */ + private int numClinitMethods; - private int counter; + /** The MethodVisitor for the merged <clinit> method. */ + private MethodVisitor mergedClinitVisitor; - public StaticInitMerger(final String prefix, final ClassVisitor cv) { - this(Opcodes.ASM6, prefix, cv); - } + /** + * Constructs a new {@link StaticInitMerger}. <i>Subclasses must not use this constructor</i>. + * Instead, they must use the {@link #StaticInitMerger(int, String, ClassVisitor)} version. + * + * @param prefix the prefix to use to rename the existing <clinit> methods. + * @param classVisitor the class visitor to which this visitor must delegate method calls. May be + * null. + */ + public StaticInitMerger(final String prefix, final ClassVisitor classVisitor) { + this(Opcodes.ASM7, prefix, classVisitor); + } - protected StaticInitMerger(final int api, final String prefix, - final ClassVisitor cv) { - super(api, cv); - this.prefix = prefix; - } + /** + * Constructs a new {@link StaticInitMerger}. + * + * @param api the ASM API version implemented by this visitor. Must be one of {@link + * Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. + * @param prefix the prefix to use to rename the existing <clinit> methods. + * @param classVisitor the class visitor to which this visitor must delegate method calls. May be + * null. + */ + protected StaticInitMerger(final int api, final String prefix, final ClassVisitor classVisitor) { + super(api, classVisitor); + this.renamedClinitMethodPrefix = prefix; + } - @Override - public void visit(final int version, final int access, final String name, - final String signature, final String superName, - final String[] interfaces) { - cv.visit(version, access, name, signature, superName, interfaces); - this.name = name; - } + @Override + public void visit( + final int version, + final int access, + final String name, + final String signature, + final String superName, + final String[] interfaces) { + super.visit(version, access, name, signature, superName, interfaces); + this.owner = name; + } - @Override - public MethodVisitor visitMethod(final int access, final String name, - final String desc, final String signature, final String[] exceptions) { - MethodVisitor mv; - if ("<clinit>".equals(name)) { - int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC; - String n = prefix + counter++; - mv = cv.visitMethod(a, n, desc, signature, exceptions); + @Override + public MethodVisitor visitMethod( + final int access, + final String name, + final String descriptor, + final String signature, + final String[] exceptions) { + MethodVisitor methodVisitor; + if ("<clinit>".equals(name)) { + int newAccess = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC; + String newName = renamedClinitMethodPrefix + numClinitMethods++; + methodVisitor = super.visitMethod(newAccess, newName, descriptor, signature, exceptions); - if (clinit == null) { - clinit = cv.visitMethod(a, name, desc, null, null); - } - clinit.visitMethodInsn(Opcodes.INVOKESTATIC, this.name, n, desc, - false); - } else { - mv = cv.visitMethod(access, name, desc, signature, exceptions); - } - return mv; + if (mergedClinitVisitor == null) { + mergedClinitVisitor = super.visitMethod(newAccess, name, descriptor, null, null); + } + mergedClinitVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, owner, newName, descriptor, false); + } else { + methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions); } + return methodVisitor; + } - @Override - public void visitEnd() { - if (clinit != null) { - clinit.visitInsn(Opcodes.RETURN); - clinit.visitMaxs(0, 0); - } - cv.visitEnd(); + @Override + public void visitEnd() { + if (mergedClinitVisitor != null) { + mergedClinitVisitor.visitInsn(Opcodes.RETURN); + mergedClinitVisitor.visitMaxs(0, 0); } + super.visitEnd(); + } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TableSwitchGenerator.java ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TableSwitchGenerator.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TableSwitchGenerator.java old mode 100644 new mode 100755 index 322d7bb..d83cb36 --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TableSwitchGenerator.java +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TableSwitchGenerator.java @@ -1,57 +1,51 @@ -/*** - * 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. - */ +// 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.commons; import org.apache.tapestry5.internal.plastic.asm.Label; /** * A code generator for switch statements. - * + * * @author Juozas Baliuka * @author Chris Nokleberg * @author Eric Bruneton */ public interface TableSwitchGenerator { - /** - * Generates the code for a switch case. - * - * @param key - * the switch case key. - * @param end - * a label that corresponds to the end of the switch statement. - */ - void generateCase(int key, Label end); + /** + * Generates the code for a switch case. + * + * @param key the switch case key. + * @param end a label that corresponds to the end of the switch statement. + */ + void generateCase(int key, Label end); - /** - * Generates the code for the default switch case. - */ - void generateDefault(); + /** Generates the code for the default switch case. */ + void generateDefault(); } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TryCatchBlockSorter.java ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TryCatchBlockSorter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TryCatchBlockSorter.java old mode 100644 new mode 100755 index 7b20b30..e579d76 --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TryCatchBlockSorter.java +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/TryCatchBlockSorter.java @@ -1,96 +1,119 @@ -/*** - * 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. - */ +// 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.commons; import java.util.Collections; import java.util.Comparator; - import org.apache.tapestry5.internal.plastic.asm.MethodVisitor; import org.apache.tapestry5.internal.plastic.asm.Opcodes; import org.apache.tapestry5.internal.plastic.asm.tree.MethodNode; import org.apache.tapestry5.internal.plastic.asm.tree.TryCatchBlockNode; /** - * A {@link MethodVisitor} adapter to sort the exception handlers. The handlers - * are sorted in a method innermost-to-outermost. This allows the programmer to - * add handlers without worrying about ordering them correctly with respect to - * existing, in-code handlers. - * - * Behavior is only defined for properly-nested handlers. If any "try" blocks - * overlap (something that isn't possible in Java code) then this may not do - * what you want. In fact, this adapter just sorts by the length of the "try" - * block, taking advantage of the fact that a given try block must be larger - * than any block it contains). - * + * A {@link MethodVisitor} adapter to sort the exception handlers. The handlers are sorted in a + * method innermost-to-outermost. This allows the programmer to add handlers without worrying about + * ordering them correctly with respect to existing, in-code handlers. + * + * <p>Behavior is only defined for properly-nested handlers. If any "try" blocks overlap (something + * that isn't possible in Java code) then this may not do what you want. In fact, this adapter just + * sorts by the length of the "try" block, taking advantage of the fact that a given try block must + * be larger than any block it contains). + * * @author Adrian Sampson */ public class TryCatchBlockSorter extends MethodNode { - public TryCatchBlockSorter(final MethodVisitor mv, final int access, - final String name, final String desc, final String signature, - final String[] exceptions) { - this(Opcodes.ASM6, mv, access, name, desc, signature, exceptions); + /** + * Constructs a new {@link TryCatchBlockSorter}. + * + * @param methodVisitor the method visitor to which this visitor must delegate method calls. May + * be {@literal null}. + * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates if + * the method is synthetic and/or deprecated. + * @param name the method's name. + * @param descriptor the method's descriptor (see {@link org.apache.tapestry5.internal.plastic.asm.Type}). + * @param signature the method's signature. May be {@literal null} if the method parameters, + * return type and exceptions do not use generic types. + * @param exceptions the internal names of the method's exception classes (see {@link + * org.apache.tapestry5.internal.plastic.asm.Type#getInternalName()}). May be {@literal null}. + */ + public TryCatchBlockSorter( + final MethodVisitor methodVisitor, + final int access, + final String name, + final String descriptor, + final String signature, + final String[] exceptions) { + this(Opcodes.ASM7, methodVisitor, access, name, descriptor, signature, exceptions); + if (getClass() != TryCatchBlockSorter.class) { + throw new IllegalStateException(); } + } - protected TryCatchBlockSorter(final int api, final MethodVisitor mv, - final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - super(api, access, name, desc, signature, exceptions); - this.mv = mv; - } + protected TryCatchBlockSorter( + final int api, + final MethodVisitor methodVisitor, + final int access, + final String name, + final String descriptor, + final String signature, + final String[] exceptions) { + super(api, access, name, descriptor, signature, exceptions); + this.mv = methodVisitor; + } - @Override - public void visitEnd() { - // Compares TryCatchBlockNodes by the length of their "try" block. - Comparator<TryCatchBlockNode> comp = new Comparator<TryCatchBlockNode>() { + @Override + public void visitEnd() { + // Sort the TryCatchBlockNode elements by the length of their "try" block. + Collections.sort( + tryCatchBlocks, + new Comparator<TryCatchBlockNode>() { - public int compare(TryCatchBlockNode t1, TryCatchBlockNode t2) { - int len1 = blockLength(t1); - int len2 = blockLength(t2); - return len1 - len2; - } + @Override + public int compare( + final TryCatchBlockNode tryCatchBlockNode1, + final TryCatchBlockNode tryCatchBlockNode2) { + return blockLength(tryCatchBlockNode1) - blockLength(tryCatchBlockNode2); + } - private int blockLength(TryCatchBlockNode block) { - int startidx = instructions.indexOf(block.start); - int endidx = instructions.indexOf(block.end); - return endidx - startidx; - } - }; - Collections.sort(tryCatchBlocks, comp); - // Updates the 'target' of each try catch block annotation. - for (int i = 0; i < tryCatchBlocks.size(); ++i) { - tryCatchBlocks.get(i).updateIndex(i); - } - if (mv != null) { - accept(mv); - } + private int blockLength(final TryCatchBlockNode tryCatchBlockNode) { + int startIndex = instructions.indexOf(tryCatchBlockNode.start); + int endIndex = instructions.indexOf(tryCatchBlockNode.end); + return endIndex - startIndex; + } + }); + // Update the 'target' of each try catch block annotation. + for (int i = 0; i < tryCatchBlocks.size(); ++i) { + tryCatchBlocks.get(i).updateIndex(i); + } + if (mv != null) { + accept(mv); } + } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/package.html ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/package.html b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/commons/package.html old mode 100644 new mode 100755 http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/package.html ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/package.html b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/package.html old mode 100644 new mode 100755 index 2d4a765..85de04d --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/package.html +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/package.html @@ -32,7 +32,7 @@ Provides a small and fast bytecode manipulation framework. <p> -The <a href="http://www.objectweb.org/asm">ASM</a> framework is organized +The <a href="http://asm.ow2.org/">ASM</a> framework is organized around the {@link org.objectweb.asm.ClassVisitor ClassVisitor}, {@link org.objectweb.asm.FieldVisitor FieldVisitor}, {@link org.objectweb.asm.MethodVisitor MethodVisitor} and @@ -52,8 +52,7 @@ In order to generate a class from scratch, only the {@link org.objectweb.asm.ClassWriter ClassWriter} class is necessary. Indeed, in order to generate a class, one must just call its visit<i>Xxx</i> methods with the appropriate arguments to generate the desired fields -and methods. See the "helloworld" example in the ASM distribution for -more details about class generation. +and methods. <p> In order to modify existing classes, one must use a {@link @@ -68,19 +67,7 @@ modification process. In order to make it easier to implement such class modifiers, the {@link org.objectweb.asm.ClassVisitor ClassVisitor} and {@link org.objectweb.asm.MethodVisitor MethodVisitor} classes delegate by default all the method calls they receive to an -optional visitor. See the "adapt" example in the ASM -distribution for more details about class modification. - -<p> -The size of the core ASM library, <tt>asm.jar</tt>, is only 45KB, which is much -smaller than the size of the -<a href="http://jakarta.apache.org/bcel">BCEL</a> library (504KB), and than the -size of the -<a href="http://serp.sourceforge.net">SERP</a> library (150KB). ASM is also -much faster than these tools. Indeed the overhead of a load time class -transformation process is of the order of 60% with ASM, 700% or more with BCEL, -and 1100% or more with SERP (see the <tt>test/perf</tt> directory in the ASM -distribution)! +optional visitor. @since ASM 1.3 </body>