http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureReader.java ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureReader.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureReader.java old mode 100644 new mode 100755 index 878cd8d..d1c063c --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureReader.java +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureReader.java @@ -1,228 +1,252 @@ -/*** - * 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.signature; /** - * A type signature parser to make a signature visitor visit an existing - * signature. - * + * A parser for signature literals, as defined in the Java Virtual Machine Specification (JVMS), to + * visit them with a SignatureVisitor. + * + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1">JVMS + * 4.7.9.1</a> * @author Thomas Hallgren * @author Eric Bruneton */ public class SignatureReader { - /** - * The signature to be read. - */ - private final String signature; - - /** - * Constructs a {@link SignatureReader} for the given signature. - * - * @param signature - * A <i>ClassSignature</i>, <i>MethodTypeSignature</i>, or - * <i>FieldTypeSignature</i>. - */ - public SignatureReader(final String signature) { - this.signature = signature; - } + /** The JVMS signature to be read. */ + private final String signatureValue; + + /** + * Constructs a {@link SignatureReader} for the given signature. + * + * @param signature A <i>JavaTypeSignature</i>, <i>ClassSignature</i> or <i>MethodSignature</i>. + */ + public SignatureReader(final String signature) { + this.signatureValue = signature; + } - /** - * Makes the given visitor visit the signature of this - * {@link SignatureReader}. This signature is the one specified in the - * constructor (see {@link #SignatureReader(String) SignatureReader}). This - * method is intended to be called on a {@link SignatureReader} that was - * created using a <i>ClassSignature</i> (such as the <code>signature</code> - * parameter of the {@link org.objectweb.asm.ClassVisitor#visit - * ClassVisitor.visit} method) or a <i>MethodTypeSignature</i> (such as the - * <code>signature</code> parameter of the - * {@link org.objectweb.asm.ClassVisitor#visitMethod - * ClassVisitor.visitMethod} method). - * - * @param v - * the visitor that must visit this signature. - */ - public void accept(final SignatureVisitor v) { - String signature = this.signature; - int len = signature.length(); - int pos; - char c; - - if (signature.charAt(0) == '<') { - pos = 2; - do { - int end = signature.indexOf(':', pos); - v.visitFormalTypeParameter(signature.substring(pos - 1, end)); - pos = end + 1; - - c = signature.charAt(pos); - if (c == 'L' || c == '[' || c == 'T') { - pos = parseType(signature, pos, v.visitClassBound()); - } - - while ((c = signature.charAt(pos++)) == ':') { - pos = parseType(signature, pos, v.visitInterfaceBound()); - } - } while (c != '>'); - } else { - pos = 0; + /** + * Makes the given visitor visit the signature of this {@link SignatureReader}. This signature is + * the one specified in the constructor (see {@link #SignatureReader}). This method is intended to + * be called on a {@link SignatureReader} that was created using a <i>ClassSignature</i> (such as + * the <code>signature</code> parameter of the {@link org.apache.tapestry5.internal.plastic.asm.ClassVisitor#visit} + * method) or a <i>MethodSignature</i> (such as the <code>signature</code> parameter of the {@link + * org.apache.tapestry5.internal.plastic.asm.ClassVisitor#visitMethod} method). + * + * @param signatureVistor the visitor that must visit this signature. + */ + public void accept(final SignatureVisitor signatureVistor) { + String signature = this.signatureValue; + int length = signature.length(); + int offset; // Current offset in the parsed signature (parsed from left to right). + char currentChar; // The signature character at 'offset', or just before. + + // If the signature starts with '<', it starts with TypeParameters, i.e. a formal type parameter + // identifier, followed by one or more pair ':',ReferenceTypeSignature (for its class bound and + // interface bounds). + if (signature.charAt(0) == '<') { + // Invariant: offset points to the second character of a formal type parameter name at the + // beginning of each iteration of the loop below. + offset = 2; + do { + // The formal type parameter name is everything between offset - 1 and the first ':'. + int classBoundStartOffset = signature.indexOf(':', offset); + signatureVistor.visitFormalTypeParameter( + signature.substring(offset - 1, classBoundStartOffset)); + + // If the character after the ':' class bound marker is not the start of a + // ReferenceTypeSignature, it means the class bound is empty (which is a valid case). + offset = classBoundStartOffset + 1; + currentChar = signature.charAt(offset); + if (currentChar == 'L' || currentChar == '[' || currentChar == 'T') { + offset = parseType(signature, offset, signatureVistor.visitClassBound()); } - if (signature.charAt(pos) == '(') { - pos++; - while (signature.charAt(pos) != ')') { - pos = parseType(signature, pos, v.visitParameterType()); - } - pos = parseType(signature, pos + 1, v.visitReturnType()); - while (pos < len) { - pos = parseType(signature, pos + 1, v.visitExceptionType()); - } - } else { - pos = parseType(signature, pos, v.visitSuperclass()); - while (pos < len) { - pos = parseType(signature, pos, v.visitInterface()); - } + // While the character after the class bound or after the last parsed interface bound + // is ':', we need to parse another interface bound. + while ((currentChar = signature.charAt(offset++)) == ':') { + offset = parseType(signature, offset, signatureVistor.visitInterfaceBound()); } + + // At this point a TypeParameter has been fully parsed, and we need to parse the next one + // (note that currentChar is now the first character of the next TypeParameter, and that + // offset points to the second character), unless the character just after this + // TypeParameter signals the end of the TypeParameters. + } while (currentChar != '>'); + } else { + offset = 0; } - /** - * Makes the given visitor visit the signature of this - * {@link SignatureReader}. This signature is the one specified in the - * constructor (see {@link #SignatureReader(String) SignatureReader}). This - * method is intended to be called on a {@link SignatureReader} that was - * created using a <i>FieldTypeSignature</i>, such as the - * <code>signature</code> parameter of the - * {@link org.objectweb.asm.ClassVisitor#visitField ClassVisitor.visitField} - * or {@link org.objectweb.asm.MethodVisitor#visitLocalVariable - * MethodVisitor.visitLocalVariable} methods. - * - * @param v - * the visitor that must visit this signature. - */ - public void acceptType(final SignatureVisitor v) { - parseType(this.signature, 0, v); + // If the (optional) TypeParameters is followed by '(' this means we are parsing a + // MethodSignature, which has JavaTypeSignature type inside parentheses, followed by a Result + // type and optional ThrowsSignature types. + if (signature.charAt(offset) == '(') { + offset++; + while (signature.charAt(offset) != ')') { + offset = parseType(signature, offset, signatureVistor.visitParameterType()); + } + // Use offset + 1 to skip ')'. + offset = parseType(signature, offset + 1, signatureVistor.visitReturnType()); + while (offset < length) { + // Use offset + 1 to skip the first character of a ThrowsSignature, i.e. '^'. + offset = parseType(signature, offset + 1, signatureVistor.visitExceptionType()); + } + } else { + // Otherwise we are parsing a ClassSignature (by hypothesis on the method input), which has + // one or more ClassTypeSignature for the super class and the implemented interfaces. + offset = parseType(signature, offset, signatureVistor.visitSuperclass()); + while (offset < length) { + offset = parseType(signature, offset, signatureVistor.visitInterface()); + } } + } + + /** + * Makes the given visitor visit the signature of this {@link SignatureReader}. This signature is + * the one specified in the constructor (see {@link #SignatureReader}). This method is intended to + * be called on a {@link SignatureReader} that was created using a <i>JavaTypeSignature</i>, such + * as the <code>signature</code> parameter of the {@link + * org.apache.tapestry5.internal.plastic.asm.ClassVisitor#visitField} or {@link + * org.apache.tapestry5.internal.plastic.asm.MethodVisitor#visitLocalVariable} methods. + * + * @param signatureVisitor the visitor that must visit this signature. + */ + public void acceptType(final SignatureVisitor signatureVisitor) { + parseType(signatureValue, 0, signatureVisitor); + } + + /** + * Parses a JavaTypeSignature and makes the given visitor visit it. + * + * @param signature a string containing the signature that must be parsed. + * @param startOffset index of the first character of the signature to parsed. + * @param signatureVisitor the visitor that must visit this signature. + * @return the index of the first character after the parsed signature. + */ + private static int parseType( + final String signature, final int startOffset, final SignatureVisitor signatureVisitor) { + int offset = startOffset; // Current offset in the parsed signature. + char currentChar = signature.charAt(offset++); // The signature character at 'offset'. + + // Switch based on the first character of the JavaTypeSignature, which indicates its kind. + switch (currentChar) { + case 'Z': + case 'C': + case 'B': + case 'S': + case 'I': + case 'F': + case 'J': + case 'D': + case 'V': + // Case of a BaseType or a VoidDescriptor. + signatureVisitor.visitBaseType(currentChar); + return offset; + + case '[': + // Case of an ArrayTypeSignature, a '[' followed by a JavaTypeSignature. + return parseType(signature, offset, signatureVisitor.visitArrayType()); - /** - * Parses a field type signature and makes the given visitor visit it. - * - * @param signature - * a string containing the signature that must be parsed. - * @param pos - * index of the first character of the signature to parsed. - * @param v - * the visitor that must visit this signature. - * @return the index of the first character after the parsed signature. - */ - private static int parseType(final String signature, int pos, - final SignatureVisitor v) { - char c; - int start, end; - boolean visited, inner; - String name; - - switch (c = signature.charAt(pos++)) { - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - case 'F': - case 'J': - case 'D': - case 'V': - v.visitBaseType(c); - return pos; - - case '[': - return parseType(signature, pos, v.visitArrayType()); - - case 'T': - end = signature.indexOf(';', pos); - v.visitTypeVariable(signature.substring(pos, end)); - return end + 1; - - default: // case 'L': - start = pos; + case 'T': + // Case of TypeVariableSignature, an identifier between 'T' and ';'. + int endOffset = signature.indexOf(';', offset); + signatureVisitor.visitTypeVariable(signature.substring(offset, endOffset)); + return endOffset + 1; + + case 'L': + // Case of a ClassTypeSignature, which ends with ';'. + // These signatures have a main class type followed by zero or more inner class types + // (separated by '.'). Each can have type arguments, inside '<' and '>'. + int start = offset; // The start offset of the currently parsed main or inner class name. + boolean visited = false; // Whether the currently parsed class name has been visited. + boolean inner = false; // Whether we are currently parsing an inner class type. + // Parses the signature, one character at a time. + while (true) { + currentChar = signature.charAt(offset++); + if (currentChar == '.' || currentChar == ';') { + // If a '.' or ';' is encountered, this means we have fully parsed the main class name + // or an inner class name. This name may already have been visited it is was followed by + // type arguments between '<' and '>'. If not, we need to visit it here. + if (!visited) { + String name = signature.substring(start, offset - 1); + if (inner) { + signatureVisitor.visitInnerClassType(name); + } else { + signatureVisitor.visitClassType(name); + } + } + // If we reached the end of the ClassTypeSignature return, otherwise start the parsing + // of a new class name, which is necessarily an inner class name. + if (currentChar == ';') { + signatureVisitor.visitEnd(); + break; + } + start = offset; visited = false; - inner = false; - for (;;) { - switch (c = signature.charAt(pos++)) { - case '.': - case ';': - if (!visited) { - name = signature.substring(start, pos - 1); - if (inner) { - v.visitInnerClassType(name); - } else { - v.visitClassType(name); - } - } - if (c == ';') { - v.visitEnd(); - return pos; - } - start = pos; - visited = false; - inner = true; - break; - - case '<': - name = signature.substring(start, pos - 1); - if (inner) { - v.visitInnerClassType(name); - } else { - v.visitClassType(name); - } - visited = true; - top: for (;;) { - switch (c = signature.charAt(pos)) { - case '>': - break top; - case '*': - ++pos; - v.visitTypeArgument(); - break; - case '+': - case '-': - pos = parseType(signature, pos + 1, - v.visitTypeArgument(c)); - break; - default: - pos = parseType(signature, pos, - v.visitTypeArgument('=')); - break; - } - } - } + inner = true; + } else if (currentChar == '<') { + // If a '<' is encountered, this means we have fully parsed the main class name or an + // inner class name, and that we now need to parse TypeArguments. First, we need to + // visit the parsed class name. + String name = signature.substring(start, offset - 1); + if (inner) { + signatureVisitor.visitInnerClassType(name); + } else { + signatureVisitor.visitClassType(name); } + visited = true; + // Now, parse the TypeArgument(s), one at a time. + while ((currentChar = signature.charAt(offset)) != '>') { + switch (currentChar) { + case '*': + // Unbounded TypeArgument. + ++offset; + signatureVisitor.visitTypeArgument(); + break; + case '+': + case '-': + // Extends or Super TypeArgument. Use offset + 1 to skip the '+' or '-'. + offset = + parseType( + signature, offset + 1, signatureVisitor.visitTypeArgument(currentChar)); + break; + default: + // Instanceof TypeArgument. The '=' is implicit. + offset = parseType(signature, offset, signatureVisitor.visitTypeArgument('=')); + break; + } + } + } } + return offset; + + default: + throw new IllegalArgumentException(); } + } }
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureVisitor.java ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureVisitor.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureVisitor.java old mode 100644 new mode 100755 index 4277ade..3f0cc9a --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureVisitor.java +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureVisitor.java @@ -1,238 +1,203 @@ -/*** - * 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.signature; import org.apache.tapestry5.internal.plastic.asm.Opcodes; /** - * A visitor to visit a generic signature. The methods of this interface must be - * called in one of the three following orders (the last one is the only valid - * order for a {@link SignatureVisitor} that is returned by a method of this - * interface): + * A visitor to visit a generic signature. The methods of this interface must be called in one of + * the three following orders (the last one is the only valid order for a {@link SignatureVisitor} + * that is returned by a method of this interface): + * * <ul> - * <li><i>ClassSignature</i> = ( <tt>visitFormalTypeParameter</tt> - * <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* ( - * <tt>visitSuperclass</tt> <tt>visitInterface</tt>* )</li> - * <li><i>MethodSignature</i> = ( <tt>visitFormalTypeParameter</tt> - * <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* ( - * <tt>visitParameterType</tt>* <tt>visitReturnType</tt> - * <tt>visitExceptionType</tt>* )</li> - * <li><i>TypeSignature</i> = <tt>visitBaseType</tt> | - * <tt>visitTypeVariable</tt> | <tt>visitArrayType</tt> | ( - * <tt>visitClassType</tt> <tt>visitTypeArgument</tt>* ( - * <tt>visitInnerClassType</tt> <tt>visitTypeArgument</tt>* )* <tt>visitEnd</tt> - * ) )</li> + * <li><i>ClassSignature</i> = ( {@code visitFormalTypeParameter} {@code visitClassBound}? {@code + * visitInterfaceBound}* )* ({@code visitSuperclass} {@code visitInterface}* ) + * <li><i>MethodSignature</i> = ( {@code visitFormalTypeParameter} {@code visitClassBound}? {@code + * visitInterfaceBound}* )* ({@code visitParameterType}* {@code visitReturnType} {@code + * visitExceptionType}* ) + * <li><i>TypeSignature</i> = {@code visitBaseType} | {@code visitTypeVariable} | {@code + * visitArrayType} | ( {@code visitClassType} {@code visitTypeArgument}* ( {@code + * visitInnerClassType} {@code visitTypeArgument}* )* {@code visitEnd} ) ) * </ul> - * + * * @author Thomas Hallgren * @author Eric Bruneton */ public abstract class SignatureVisitor { - /** - * Wildcard for an "extends" type argument. - */ - public final static char EXTENDS = '+'; - - /** - * Wildcard for a "super" type argument. - */ - public final static char SUPER = '-'; - - /** - * Wildcard for a normal type argument. - */ - public final static char INSTANCEOF = '='; - - /** - * The ASM API version implemented by this visitor. The value of this field - * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. - */ - protected final int api; - - /** - * Constructs a new {@link SignatureVisitor}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. - */ - public SignatureVisitor(final int api) { - if (api < Opcodes.ASM4 || api > Opcodes.ASM6) { - throw new IllegalArgumentException(); - } - this.api = api; - } - - /** - * Visits a formal type parameter. - * - * @param name - * the name of the formal parameter. - */ - public void visitFormalTypeParameter(String name) { - } - - /** - * Visits the class bound of the last visited formal type parameter. - * - * @return a non null visitor to visit the signature of the class bound. - */ - public SignatureVisitor visitClassBound() { - return this; - } - - /** - * Visits an interface bound of the last visited formal type parameter. - * - * @return a non null visitor to visit the signature of the interface bound. - */ - public SignatureVisitor visitInterfaceBound() { - return this; - } - - /** - * Visits the type of the super class. - * - * @return a non null visitor to visit the signature of the super class - * type. - */ - public SignatureVisitor visitSuperclass() { - return this; - } - - /** - * Visits the type of an interface implemented by the class. - * - * @return a non null visitor to visit the signature of the interface type. - */ - public SignatureVisitor visitInterface() { - return this; - } - - /** - * Visits the type of a method parameter. - * - * @return a non null visitor to visit the signature of the parameter type. - */ - public SignatureVisitor visitParameterType() { - return this; - } - - /** - * Visits the return type of the method. - * - * @return a non null visitor to visit the signature of the return type. - */ - public SignatureVisitor visitReturnType() { - return this; - } - - /** - * Visits the type of a method exception. - * - * @return a non null visitor to visit the signature of the exception type. - */ - public SignatureVisitor visitExceptionType() { - return this; - } - - /** - * Visits a signature corresponding to a primitive type. - * - * @param descriptor - * the descriptor of the primitive type, or 'V' for <tt>void</tt> - * . - */ - public void visitBaseType(char descriptor) { - } - - /** - * Visits a signature corresponding to a type variable. - * - * @param name - * the name of the type variable. - */ - public void visitTypeVariable(String name) { - } - - /** - * Visits a signature corresponding to an array type. - * - * @return a non null visitor to visit the signature of the array element - * type. - */ - public SignatureVisitor visitArrayType() { - return this; - } - - /** - * Starts the visit of a signature corresponding to a class or interface - * type. - * - * @param name - * the internal name of the class or interface. - */ - public void visitClassType(String name) { - } - - /** - * Visits an inner class. - * - * @param name - * the local name of the inner class in its enclosing class. - */ - public void visitInnerClassType(String name) { - } - - /** - * Visits an unbounded type argument of the last visited class or inner - * class type. - */ - public void visitTypeArgument() { - } - - /** - * Visits a type argument of the last visited class or inner class type. - * - * @param wildcard - * '+', '-' or '='. - * @return a non null visitor to visit the signature of the type argument. - */ - public SignatureVisitor visitTypeArgument(char wildcard) { - return this; - } - - /** - * Ends the visit of a signature corresponding to a class or interface type. - */ - public void visitEnd() { - } + /** Wildcard for an "extends" type argument. */ + public static final char EXTENDS = '+'; + + /** Wildcard for a "super" type argument. */ + public static final char SUPER = '-'; + + /** Wildcard for a normal type argument. */ + public static final char INSTANCEOF = '='; + + /** + * The ASM API version implemented by this visitor. The value of this field must be one of {@link + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. + */ + protected final int api; + + /** + * Constructs a new {@link SignatureVisitor}. + * + * @param api the ASM API version implemented by this visitor. Must be one of {@link + * Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. + */ + public SignatureVisitor(final int api) { + if (api != Opcodes.ASM6 && api != Opcodes.ASM5 && api != Opcodes.ASM4 && api != Opcodes.ASM7) { + throw new IllegalArgumentException(); + } + this.api = api; + } + + /** + * Visits a formal type parameter. + * + * @param name the name of the formal parameter. + */ + public void visitFormalTypeParameter(final String name) {} + + /** + * Visits the class bound of the last visited formal type parameter. + * + * @return a non null visitor to visit the signature of the class bound. + */ + public SignatureVisitor visitClassBound() { + return this; + } + + /** + * Visits an interface bound of the last visited formal type parameter. + * + * @return a non null visitor to visit the signature of the interface bound. + */ + public SignatureVisitor visitInterfaceBound() { + return this; + } + + /** + * Visits the type of the super class. + * + * @return a non null visitor to visit the signature of the super class type. + */ + public SignatureVisitor visitSuperclass() { + return this; + } + + /** + * Visits the type of an interface implemented by the class. + * + * @return a non null visitor to visit the signature of the interface type. + */ + public SignatureVisitor visitInterface() { + return this; + } + + /** + * Visits the type of a method parameter. + * + * @return a non null visitor to visit the signature of the parameter type. + */ + public SignatureVisitor visitParameterType() { + return this; + } + + /** + * Visits the return type of the method. + * + * @return a non null visitor to visit the signature of the return type. + */ + public SignatureVisitor visitReturnType() { + return this; + } + + /** + * Visits the type of a method exception. + * + * @return a non null visitor to visit the signature of the exception type. + */ + public SignatureVisitor visitExceptionType() { + return this; + } + + /** + * Visits a signature corresponding to a primitive type. + * + * @param descriptor the descriptor of the primitive type, or 'V' for {@code void} . + */ + public void visitBaseType(final char descriptor) {} + + /** + * Visits a signature corresponding to a type variable. + * + * @param name the name of the type variable. + */ + public void visitTypeVariable(final String name) {} + + /** + * Visits a signature corresponding to an array type. + * + * @return a non null visitor to visit the signature of the array element type. + */ + public SignatureVisitor visitArrayType() { + return this; + } + + /** + * Starts the visit of a signature corresponding to a class or interface type. + * + * @param name the internal name of the class or interface. + */ + public void visitClassType(final String name) {} + + /** + * Visits an inner class. + * + * @param name the local name of the inner class in its enclosing class. + */ + public void visitInnerClassType(final String name) {} + + /** Visits an unbounded type argument of the last visited class or inner class type. */ + public void visitTypeArgument() {} + + /** + * Visits a type argument of the last visited class or inner class type. + * + * @param wildcard '+', '-' or '='. + * @return a non null visitor to visit the signature of the type argument. + */ + public SignatureVisitor visitTypeArgument(final char wildcard) { + return this; + } + + /** Ends the visit of a signature corresponding to a class or interface type. */ + public void visitEnd() {} } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureWriter.java ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureWriter.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureWriter.java old mode 100644 new mode 100755 index 8d98cd1..4adc4e2 --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureWriter.java +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/SignatureWriter.java @@ -1,227 +1,240 @@ -/*** - * 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.signature; import org.apache.tapestry5.internal.plastic.asm.Opcodes; /** - * A signature visitor that generates signatures in string format. - * + * A SignatureVisitor that generates signature literals, as defined in the Java Virtual Machine + * Specification (JVMS). + * + * @see <a href="https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1">JVMS + * 4.7.9.1</a> * @author Thomas Hallgren * @author Eric Bruneton */ public class SignatureWriter extends SignatureVisitor { - /** - * Builder used to construct the signature. - */ - private final StringBuilder buf = new StringBuilder(); - - /** - * Indicates if the signature contains formal type parameters. - */ - private boolean hasFormals; - - /** - * Indicates if the signature contains method parameter types. - */ - private boolean hasParameters; - - /** - * Stack used to keep track of class types that have arguments. Each element - * of this stack is a boolean encoded in one bit. The top of the stack is - * the lowest order bit. Pushing false = *2, pushing true = *2+1, popping = - * /2. - */ - private int argumentStack; - - /** - * Constructs a new {@link SignatureWriter} object. - */ - public SignatureWriter() { - super(Opcodes.ASM6); - } - - // ------------------------------------------------------------------------ - // Implementation of the SignatureVisitor interface - // ------------------------------------------------------------------------ - - @Override - public void visitFormalTypeParameter(final String name) { - if (!hasFormals) { - hasFormals = true; - buf.append('<'); - } - buf.append(name); - buf.append(':'); - } - - @Override - public SignatureVisitor visitClassBound() { - return this; - } - - @Override - public SignatureVisitor visitInterfaceBound() { - buf.append(':'); - return this; - } - - @Override - public SignatureVisitor visitSuperclass() { - endFormals(); - return this; - } - - @Override - public SignatureVisitor visitInterface() { - return this; - } - - @Override - public SignatureVisitor visitParameterType() { - endFormals(); - if (!hasParameters) { - hasParameters = true; - buf.append('('); - } - return this; - } - - @Override - public SignatureVisitor visitReturnType() { - endFormals(); - if (!hasParameters) { - buf.append('('); - } - buf.append(')'); - return this; - } - - @Override - public SignatureVisitor visitExceptionType() { - buf.append('^'); - return this; - } - - @Override - public void visitBaseType(final char descriptor) { - buf.append(descriptor); - } - - @Override - public void visitTypeVariable(final String name) { - buf.append('T'); - buf.append(name); - buf.append(';'); - } - - @Override - public SignatureVisitor visitArrayType() { - buf.append('['); - return this; - } - - @Override - public void visitClassType(final String name) { - buf.append('L'); - buf.append(name); - argumentStack *= 2; - } - - @Override - public void visitInnerClassType(final String name) { - endArguments(); - buf.append('.'); - buf.append(name); - argumentStack *= 2; - } - - @Override - public void visitTypeArgument() { - if (argumentStack % 2 == 0) { - ++argumentStack; - buf.append('<'); - } - buf.append('*'); - } - - @Override - public SignatureVisitor visitTypeArgument(final char wildcard) { - if (argumentStack % 2 == 0) { - ++argumentStack; - buf.append('<'); - } - if (wildcard != '=') { - buf.append(wildcard); - } - return this; - } - - @Override - public void visitEnd() { - endArguments(); - buf.append(';'); - } - - /** - * Returns the signature that was built by this signature writer. - * - * @return the signature that was built by this signature writer. - */ - @Override - public String toString() { - return buf.toString(); - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - /** - * Ends the formal type parameters section of the signature. - */ - private void endFormals() { - if (hasFormals) { - hasFormals = false; - buf.append('>'); - } - } - - /** - * Ends the type arguments of a class or inner class type. - */ - private void endArguments() { - if (argumentStack % 2 != 0) { - buf.append('>'); - } - argumentStack /= 2; - } -} \ No newline at end of file + /** The builder used to construct the visited signature. */ + private final StringBuilder stringBuilder = new StringBuilder(); + + /** Whether the visited signature contains formal type parameters. */ + private boolean hasFormals; + + /** Whether the visited signature contains method parameter types. */ + private boolean hasParameters; + + /** + * The stack used to keep track of class types that have arguments. Each element of this stack is + * a boolean encoded in one bit. The top of the stack is the least significant bit. Pushing false + * = *2, pushing true = *2+1, popping = /2. + * + * <p>Class type arguments must be surrounded with '<' and '>' and, because + * + * <ol> + * <li>class types can be nested (because type arguments can themselves be class types), + * <li>SignatureWriter always returns 'this' in each visit* method (to avoid allocating new + * SignatureWriter instances), + * </ol> + * + * <p>we need a stack to properly balance these 'parentheses'. A new element is pushed on this + * stack for each new visited type, and popped when the visit of this type ends (either is + * visitEnd, or because visitInnerClassType is called). + */ + private int argumentStack; + + /** Constructs a new {@link SignatureWriter}. */ + public SignatureWriter() { + super(Opcodes.ASM7); + } + + // ----------------------------------------------------------------------------------------------- + // Implementation of the SignatureVisitor interface + // ----------------------------------------------------------------------------------------------- + + @Override + public void visitFormalTypeParameter(final String name) { + if (!hasFormals) { + hasFormals = true; + stringBuilder.append('<'); + } + stringBuilder.append(name); + stringBuilder.append(':'); + } + + @Override + public SignatureVisitor visitClassBound() { + return this; + } + + @Override + public SignatureVisitor visitInterfaceBound() { + stringBuilder.append(':'); + return this; + } + + @Override + public SignatureVisitor visitSuperclass() { + endFormals(); + return this; + } + + @Override + public SignatureVisitor visitInterface() { + return this; + } + + @Override + public SignatureVisitor visitParameterType() { + endFormals(); + if (!hasParameters) { + hasParameters = true; + stringBuilder.append('('); + } + return this; + } + + @Override + public SignatureVisitor visitReturnType() { + endFormals(); + if (!hasParameters) { + stringBuilder.append('('); + } + stringBuilder.append(')'); + return this; + } + + @Override + public SignatureVisitor visitExceptionType() { + stringBuilder.append('^'); + return this; + } + + @Override + public void visitBaseType(final char descriptor) { + stringBuilder.append(descriptor); + } + + @Override + public void visitTypeVariable(final String name) { + stringBuilder.append('T'); + stringBuilder.append(name); + stringBuilder.append(';'); + } + + @Override + public SignatureVisitor visitArrayType() { + stringBuilder.append('['); + return this; + } + + @Override + public void visitClassType(final String name) { + stringBuilder.append('L'); + stringBuilder.append(name); + // Pushes 'false' on the stack, meaning that this type does not have type arguments (as far as + // we can tell at this point). + argumentStack *= 2; + } + + @Override + public void visitInnerClassType(final String name) { + endArguments(); + stringBuilder.append('.'); + stringBuilder.append(name); + // Pushes 'false' on the stack, meaning that this type does not have type arguments (as far as + // we can tell at this point). + argumentStack *= 2; + } + + @Override + public void visitTypeArgument() { + // If the top of the stack is 'false', this means we are visiting the first type argument of the + // currently visited type. We therefore need to append a '<', and to replace the top stack + // element with 'true' (meaning that the current type does have type arguments). + if (argumentStack % 2 == 0) { + argumentStack |= 1; + stringBuilder.append('<'); + } + stringBuilder.append('*'); + } + + @Override + public SignatureVisitor visitTypeArgument(final char wildcard) { + // If the top of the stack is 'false', this means we are visiting the first type argument of the + // currently visited type. We therefore need to append a '<', and to replace the top stack + // element with 'true' (meaning that the current type does have type arguments). + if (argumentStack % 2 == 0) { + argumentStack |= 1; + stringBuilder.append('<'); + } + if (wildcard != '=') { + stringBuilder.append(wildcard); + } + return this; + } + + @Override + public void visitEnd() { + endArguments(); + stringBuilder.append(';'); + } + + /** + * Returns the signature that was built by this signature writer. + * + * @return the signature that was built by this signature writer. + */ + @Override + public String toString() { + return stringBuilder.toString(); + } + + // ----------------------------------------------------------------------------------------------- + // Utility methods + // ----------------------------------------------------------------------------------------------- + + /** Ends the formal type parameters section of the signature. */ + private void endFormals() { + if (hasFormals) { + hasFormals = false; + stringBuilder.append('>'); + } + } + + /** Ends the type arguments of a class or inner class type. */ + private void endArguments() { + // If the top of the stack is 'true', this means that some type arguments have been visited for + // the type whose visit is now ending. We therefore need to append a '>', and to pop one element + // from the stack. + if (argumentStack % 2 == 1) { + stringBuilder.append('>'); + } + argumentStack /= 2; + } +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/package.html ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/package.html b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/signature/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/tree/AbstractInsnNode.java ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/AbstractInsnNode.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/AbstractInsnNode.java old mode 100644 new mode 100755 index a6a01d6..9005565 --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/AbstractInsnNode.java +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/AbstractInsnNode.java @@ -1,326 +1,265 @@ -/*** - * 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.tree; import java.util.ArrayList; import java.util.List; import java.util.Map; - import org.apache.tapestry5.internal.plastic.asm.MethodVisitor; /** - * A node that represents a bytecode instruction. <i>An instruction can appear - * at most once in at most one {@link InsnList} at a time</i>. - * + * A node that represents a bytecode instruction. <i>An instruction can appear at most once in at + * most one {@link InsnList} at a time</i>. + * * @author Eric Bruneton */ public abstract class AbstractInsnNode { - /** - * The type of {@link InsnNode} instructions. - */ - public static final int INSN = 0; - - /** - * The type of {@link IntInsnNode} instructions. - */ - public static final int INT_INSN = 1; - - /** - * The type of {@link VarInsnNode} instructions. - */ - public static final int VAR_INSN = 2; - - /** - * The type of {@link TypeInsnNode} instructions. - */ - public static final int TYPE_INSN = 3; - - /** - * The type of {@link FieldInsnNode} instructions. - */ - public static final int FIELD_INSN = 4; - - /** - * The type of {@link MethodInsnNode} instructions. - */ - public static final int METHOD_INSN = 5; - - /** - * The type of {@link InvokeDynamicInsnNode} instructions. - */ - public static final int INVOKE_DYNAMIC_INSN = 6; - - /** - * The type of {@link JumpInsnNode} instructions. - */ - public static final int JUMP_INSN = 7; - - /** - * The type of {@link LabelNode} "instructions". - */ - public static final int LABEL = 8; - - /** - * The type of {@link LdcInsnNode} instructions. - */ - public static final int LDC_INSN = 9; - - /** - * The type of {@link IincInsnNode} instructions. - */ - public static final int IINC_INSN = 10; - - /** - * The type of {@link TableSwitchInsnNode} instructions. - */ - public static final int TABLESWITCH_INSN = 11; - - /** - * The type of {@link LookupSwitchInsnNode} instructions. - */ - public static final int LOOKUPSWITCH_INSN = 12; - - /** - * The type of {@link MultiANewArrayInsnNode} instructions. - */ - public static final int MULTIANEWARRAY_INSN = 13; - - /** - * The type of {@link FrameNode} "instructions". - */ - public static final int FRAME = 14; - - /** - * The type of {@link LineNumberNode} "instructions". - */ - public static final int LINE = 15; - - /** - * The opcode of this instruction. - */ - protected int opcode; - - /** - * The runtime visible type annotations of this instruction. This field is - * only used for real instructions (i.e. not for labels, frames, or line - * number nodes). This list is a list of {@link TypeAnnotationNode} objects. - * May be <tt>null</tt>. - * - * @associates org.objectweb.asm.tree.TypeAnnotationNode - * @label visible - */ - public List<TypeAnnotationNode> visibleTypeAnnotations; - - /** - * The runtime invisible type annotations of this instruction. This field is - * only used for real instructions (i.e. not for labels, frames, or line - * number nodes). This list is a list of {@link TypeAnnotationNode} objects. - * May be <tt>null</tt>. - * - * @associates org.objectweb.asm.tree.TypeAnnotationNode - * @label invisible - */ - public List<TypeAnnotationNode> invisibleTypeAnnotations; - - /** - * Previous instruction in the list to which this instruction belongs. - */ - AbstractInsnNode prev; - - /** - * Next instruction in the list to which this instruction belongs. - */ - AbstractInsnNode next; - - /** - * Index of this instruction in the list to which it belongs. The value of - * this field is correct only when {@link InsnList#cache} is not null. A - * value of -1 indicates that this instruction does not belong to any - * {@link InsnList}. - */ - int index; - - /** - * Constructs a new {@link AbstractInsnNode}. - * - * @param opcode - * the opcode of the instruction to be constructed. - */ - protected AbstractInsnNode(final int opcode) { - this.opcode = opcode; - this.index = -1; - } - - /** - * Returns the opcode of this instruction. - * - * @return the opcode of this instruction. - */ - public int getOpcode() { - return opcode; - } + /** The type of {@link InsnNode} instructions. */ + public static final int INSN = 0; + + /** The type of {@link IntInsnNode} instructions. */ + public static final int INT_INSN = 1; - /** - * Returns the type of this instruction. - * - * @return the type of this instruction, i.e. one the constants defined in - * this class. - */ - public abstract int getType(); - - /** - * Returns the previous instruction in the list to which this instruction - * belongs, if any. - * - * @return the previous instruction in the list to which this instruction - * belongs, if any. May be <tt>null</tt>. - */ - public AbstractInsnNode getPrevious() { - return prev; + /** The type of {@link VarInsnNode} instructions. */ + public static final int VAR_INSN = 2; + + /** The type of {@link TypeInsnNode} instructions. */ + public static final int TYPE_INSN = 3; + + /** The type of {@link FieldInsnNode} instructions. */ + public static final int FIELD_INSN = 4; + + /** The type of {@link MethodInsnNode} instructions. */ + public static final int METHOD_INSN = 5; + + /** The type of {@link InvokeDynamicInsnNode} instructions. */ + public static final int INVOKE_DYNAMIC_INSN = 6; + + /** The type of {@link JumpInsnNode} instructions. */ + public static final int JUMP_INSN = 7; + + /** The type of {@link LabelNode} "instructions". */ + public static final int LABEL = 8; + + /** The type of {@link LdcInsnNode} instructions. */ + public static final int LDC_INSN = 9; + + /** The type of {@link IincInsnNode} instructions. */ + public static final int IINC_INSN = 10; + + /** The type of {@link TableSwitchInsnNode} instructions. */ + public static final int TABLESWITCH_INSN = 11; + + /** The type of {@link LookupSwitchInsnNode} instructions. */ + public static final int LOOKUPSWITCH_INSN = 12; + + /** The type of {@link MultiANewArrayInsnNode} instructions. */ + public static final int MULTIANEWARRAY_INSN = 13; + + /** The type of {@link FrameNode} "instructions". */ + public static final int FRAME = 14; + + /** The type of {@link LineNumberNode} "instructions". */ + public static final int LINE = 15; + + /** The opcode of this instruction. */ + protected int opcode; + + /** + * The runtime visible type annotations of this instruction. This field is only used for real + * instructions (i.e. not for labels, frames, or line number nodes). This list is a list of {@link + * TypeAnnotationNode} objects. May be {@literal null}. + */ + public List<TypeAnnotationNode> visibleTypeAnnotations; + + /** + * The runtime invisible type annotations of this instruction. This field is only used for real + * instructions (i.e. not for labels, frames, or line number nodes). This list is a list of {@link + * TypeAnnotationNode} objects. May be {@literal null}. + */ + public List<TypeAnnotationNode> invisibleTypeAnnotations; + + /** The previous instruction in the list to which this instruction belongs. */ + AbstractInsnNode previousInsn; + + /** The next instruction in the list to which this instruction belongs. */ + AbstractInsnNode nextInsn; + + /** + * The index of this instruction in the list to which it belongs. The value of this field is + * correct only when {@link InsnList#cache} is not null. A value of -1 indicates that this + * instruction does not belong to any {@link InsnList}. + */ + int index; + + /** + * Constructs a new {@link AbstractInsnNode}. + * + * @param opcode the opcode of the instruction to be constructed. + */ + protected AbstractInsnNode(final int opcode) { + this.opcode = opcode; + this.index = -1; + } + + /** + * Returns the opcode of this instruction. + * + * @return the opcode of this instruction. + */ + public int getOpcode() { + return opcode; + } + + /** + * Returns the type of this instruction. + * + * @return the type of this instruction, i.e. one the constants defined in this class. + */ + public abstract int getType(); + + /** + * Returns the previous instruction in the list to which this instruction belongs, if any. + * + * @return the previous instruction in the list to which this instruction belongs, if any. May be + * {@literal null}. + */ + public AbstractInsnNode getPrevious() { + return previousInsn; + } + + /** + * Returns the next instruction in the list to which this instruction belongs, if any. + * + * @return the next instruction in the list to which this instruction belongs, if any. May be + * {@literal null}. + */ + public AbstractInsnNode getNext() { + return nextInsn; + } + + /** + * Makes the given method visitor visit this instruction. + * + * @param methodVisitor a method visitor. + */ + public abstract void accept(MethodVisitor methodVisitor); + + /** + * Makes the given visitor visit the annotations of this instruction. + * + * @param methodVisitor a method visitor. + */ + protected final void acceptAnnotations(final MethodVisitor methodVisitor) { + if (visibleTypeAnnotations != null) { + for (int i = 0, n = visibleTypeAnnotations.size(); i < n; ++i) { + TypeAnnotationNode typeAnnotation = visibleTypeAnnotations.get(i); + typeAnnotation.accept( + methodVisitor.visitInsnAnnotation( + typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, true)); + } } - - /** - * Returns the next instruction in the list to which this instruction - * belongs, if any. - * - * @return the next instruction in the list to which this instruction - * belongs, if any. May be <tt>null</tt>. - */ - public AbstractInsnNode getNext() { - return next; + if (invisibleTypeAnnotations != null) { + for (int i = 0, n = invisibleTypeAnnotations.size(); i < n; ++i) { + TypeAnnotationNode typeAnnotation = invisibleTypeAnnotations.get(i); + typeAnnotation.accept( + methodVisitor.visitInsnAnnotation( + typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, false)); + } } - - /** - * Makes the given code visitor visit this instruction. - * - * @param cv - * a code visitor. - */ - public abstract void accept(final MethodVisitor cv); - - /** - * Makes the given visitor visit the annotations of this instruction. - * - * @param mv - * a method visitor. - */ - protected final void acceptAnnotations(final MethodVisitor mv) { - int n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations - .size(); - for (int i = 0; i < n; ++i) { - TypeAnnotationNode an = visibleTypeAnnotations.get(i); - an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc, - true)); - } - n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations - .size(); - for (int i = 0; i < n; ++i) { - TypeAnnotationNode an = invisibleTypeAnnotations.get(i); - an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc, - false)); - } + } + + /** + * Returns a copy of this instruction. + * + * @param clonedLabels a map from LabelNodes to cloned LabelNodes. + * @return a copy of this instruction. The returned instruction does not belong to any {@link + * InsnList}. + */ + public abstract AbstractInsnNode clone(Map<LabelNode, LabelNode> clonedLabels); + + /** + * Returns the clone of the given label. + * + * @param label a label. + * @param clonedLabels a map from LabelNodes to cloned LabelNodes. + * @return the clone of the given label. + */ + static LabelNode clone(final LabelNode label, final Map<LabelNode, LabelNode> clonedLabels) { + return clonedLabels.get(label); + } + + /** + * Returns the clones of the given labels. + * + * @param labels a list of labels. + * @param clonedLabels a map from LabelNodes to cloned LabelNodes. + * @return the clones of the given labels. + */ + static LabelNode[] clone( + final List<LabelNode> labels, final Map<LabelNode, LabelNode> clonedLabels) { + LabelNode[] clones = new LabelNode[labels.size()]; + for (int i = 0, n = clones.length; i < n; ++i) { + clones[i] = clonedLabels.get(labels.get(i)); } - - /** - * Returns a copy of this instruction. - * - * @param labels - * a map from LabelNodes to cloned LabelNodes. - * @return a copy of this instruction. The returned instruction does not - * belong to any {@link InsnList}. - */ - public abstract AbstractInsnNode clone( - final Map<LabelNode, LabelNode> labels); - - /** - * Returns the clone of the given label. - * - * @param label - * a label. - * @param map - * a map from LabelNodes to cloned LabelNodes. - * @return the clone of the given label. - */ - static LabelNode clone(final LabelNode label, - final Map<LabelNode, LabelNode> map) { - return map.get(label); + return clones; + } + + /** + * Clones the annotations of the given instruction into this instruction. + * + * @param insnNode the source instruction. + * @return this instruction. + */ + protected final AbstractInsnNode cloneAnnotations(final AbstractInsnNode insnNode) { + if (insnNode.visibleTypeAnnotations != null) { + this.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(); + for (int i = 0, n = insnNode.visibleTypeAnnotations.size(); i < n; ++i) { + TypeAnnotationNode sourceAnnotation = insnNode.visibleTypeAnnotations.get(i); + TypeAnnotationNode cloneAnnotation = + new TypeAnnotationNode( + sourceAnnotation.typeRef, sourceAnnotation.typePath, sourceAnnotation.desc); + sourceAnnotation.accept(cloneAnnotation); + this.visibleTypeAnnotations.add(cloneAnnotation); + } } - - /** - * Returns the clones of the given labels. - * - * @param labels - * a list of labels. - * @param map - * a map from LabelNodes to cloned LabelNodes. - * @return the clones of the given labels. - */ - static LabelNode[] clone(final List<LabelNode> labels, - final Map<LabelNode, LabelNode> map) { - LabelNode[] clones = new LabelNode[labels.size()]; - for (int i = 0; i < clones.length; ++i) { - clones[i] = map.get(labels.get(i)); - } - return clones; - } - - /** - * Clones the annotations of the given instruction into this instruction. - * - * @param insn - * the source instruction. - * @return this instruction. - */ - protected final AbstractInsnNode cloneAnnotations( - final AbstractInsnNode insn) { - if (insn.visibleTypeAnnotations != null) { - this.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(); - for (int i = 0; i < insn.visibleTypeAnnotations.size(); ++i) { - TypeAnnotationNode src = insn.visibleTypeAnnotations.get(i); - TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef, - src.typePath, src.desc); - src.accept(ann); - this.visibleTypeAnnotations.add(ann); - } - } - if (insn.invisibleTypeAnnotations != null) { - this.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(); - for (int i = 0; i < insn.invisibleTypeAnnotations.size(); ++i) { - TypeAnnotationNode src = insn.invisibleTypeAnnotations.get(i); - TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef, - src.typePath, src.desc); - src.accept(ann); - this.invisibleTypeAnnotations.add(ann); - } - } - return this; + if (insnNode.invisibleTypeAnnotations != null) { + this.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(); + for (int i = 0, n = insnNode.invisibleTypeAnnotations.size(); i < n; ++i) { + TypeAnnotationNode sourceAnnotation = insnNode.invisibleTypeAnnotations.get(i); + TypeAnnotationNode cloneAnnotation = + new TypeAnnotationNode( + sourceAnnotation.typeRef, sourceAnnotation.typePath, sourceAnnotation.desc); + sourceAnnotation.accept(cloneAnnotation); + this.invisibleTypeAnnotations.add(cloneAnnotation); + } } + return this; + } }
