http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/MethodNode.java ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/MethodNode.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/MethodNode.java old mode 100644 new mode 100755 index 68b4e31..39114ac --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/MethodNode.java +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/MethodNode.java @@ -1,41 +1,38 @@ -/*** - * 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.Arrays; import java.util.List; - import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor; import org.apache.tapestry5.internal.plastic.asm.Attribute; import org.apache.tapestry5.internal.plastic.asm.ClassVisitor; +import org.apache.tapestry5.internal.plastic.asm.ConstantDynamic; import org.apache.tapestry5.internal.plastic.asm.Handle; import org.apache.tapestry5.internal.plastic.asm.Label; import org.apache.tapestry5.internal.plastic.asm.MethodVisitor; @@ -45,796 +42,774 @@ import org.apache.tapestry5.internal.plastic.asm.TypePath; /** * A node that represents a method. - * + * * @author Eric Bruneton */ public class MethodNode extends MethodVisitor { - /** - * The method's access flags (see {@link Opcodes}). This field also - * indicates if the method is synthetic and/or deprecated. - */ - public int access; - - /** - * The method's name. - */ - public String name; - - /** - * The method's descriptor (see {@link Type}). - */ - public String desc; - - /** - * The method's signature. May be <tt>null</tt>. - */ - public String signature; - - /** - * The internal names of the method's exception classes (see - * {@link Type#getInternalName() getInternalName}). This list is a list of - * {@link String} objects. - */ - public List<String> exceptions; - - /** - * The method parameter info (access flags and name) - */ - public List<ParameterNode> parameters; - - /** - * The runtime visible annotations of this method. This list is a list of - * {@link AnnotationNode} objects. May be <tt>null</tt>. - * - * @associates org.objectweb.asm.tree.AnnotationNode - * @label visible - */ - public List<AnnotationNode> visibleAnnotations; - - /** - * The runtime invisible annotations of this method. This list is a list of - * {@link AnnotationNode} objects. May be <tt>null</tt>. - * - * @associates org.objectweb.asm.tree.AnnotationNode - * @label invisible - */ - public List<AnnotationNode> invisibleAnnotations; - - /** - * The runtime visible type annotations of this method. 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 method. 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; - - /** - * The non standard attributes of this method. This list is a list of - * {@link Attribute} objects. May be <tt>null</tt>. - * - * @associates org.objectweb.asm.Attribute - */ - public List<Attribute> attrs; - - /** - * The default value of this annotation interface method. This field must be - * a {@link Byte}, {@link Boolean}, {@link Character}, {@link Short}, - * {@link Integer}, {@link Long}, {@link Float}, {@link Double}, - * {@link String} or {@link Type}, or an two elements String array (for - * enumeration values), a {@link AnnotationNode}, or a {@link List} of - * values of one of the preceding types. May be <tt>null</tt>. - */ - public Object annotationDefault; - - /** - * The runtime visible parameter annotations of this method. These lists are - * lists of {@link AnnotationNode} objects. May be <tt>null</tt>. - * - * @associates org.objectweb.asm.tree.AnnotationNode - * @label invisible parameters - */ - public List<AnnotationNode>[] visibleParameterAnnotations; - - /** - * The runtime invisible parameter annotations of this method. These lists - * are lists of {@link AnnotationNode} objects. May be <tt>null</tt>. - * - * @associates org.objectweb.asm.tree.AnnotationNode - * @label visible parameters - */ - public List<AnnotationNode>[] invisibleParameterAnnotations; - - /** - * The instructions of this method. This list is a list of - * {@link AbstractInsnNode} objects. - * - * @associates org.objectweb.asm.tree.AbstractInsnNode - * @label instructions - */ - public InsnList instructions; - - /** - * The try catch blocks of this method. This list is a list of - * {@link TryCatchBlockNode} objects. - * - * @associates org.objectweb.asm.tree.TryCatchBlockNode - */ - public List<TryCatchBlockNode> tryCatchBlocks; - - /** - * The maximum stack size of this method. - */ - public int maxStack; - - /** - * The maximum number of local variables of this method. - */ - public int maxLocals; - - /** - * The local variables of this method. This list is a list of - * {@link LocalVariableNode} objects. May be <tt>null</tt> - * - * @associates org.objectweb.asm.tree.LocalVariableNode - */ - public List<LocalVariableNode> localVariables; - - /** - * The visible local variable annotations of this method. This list is a - * list of {@link LocalVariableAnnotationNode} objects. May be <tt>null</tt> - * - * @associates org.objectweb.asm.tree.LocalVariableAnnotationNode - */ - public List<LocalVariableAnnotationNode> visibleLocalVariableAnnotations; - - /** - * The invisible local variable annotations of this method. This list is a - * list of {@link LocalVariableAnnotationNode} objects. May be <tt>null</tt> - * - * @associates org.objectweb.asm.tree.LocalVariableAnnotationNode - */ - public List<LocalVariableAnnotationNode> invisibleLocalVariableAnnotations; - - /** - * If the accept method has been called on this object. - */ - private boolean visited; - - /** - * Constructs an uninitialized {@link MethodNode}. <i>Subclasses must not - * use this constructor</i>. Instead, they must use the - * {@link #MethodNode(int)} version. - * - * @throws IllegalStateException - * If a subclass calls this constructor. - */ - public MethodNode() { - this(Opcodes.ASM6); - if (getClass() != MethodNode.class) { - throw new IllegalStateException(); - } - } - - /** - * Constructs an uninitialized {@link MethodNode}. - * - * @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 MethodNode(final int api) { - super(api); - this.instructions = new InsnList(); - } - - /** - * Constructs a new {@link MethodNode}. <i>Subclasses must not use this - * constructor</i>. Instead, they must use the - * {@link #MethodNode(int, int, String, String, String, String[])} version. - * - * @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 desc - * the method's descriptor (see {@link Type}). - * @param signature - * the method's signature. May be <tt>null</tt>. - * @param exceptions - * the internal names of the method's exception classes (see - * {@link Type#getInternalName() getInternalName}). May be - * <tt>null</tt>. - * @throws IllegalStateException - * If a subclass calls this constructor. - */ - public MethodNode(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - this(Opcodes.ASM6, access, name, desc, signature, exceptions); - if (getClass() != MethodNode.class) { - throw new IllegalStateException(); - } - } - - /** - * Constructs a new {@link MethodNode}. - * - * @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 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 desc - * the method's descriptor (see {@link Type}). - * @param signature - * the method's signature. May be <tt>null</tt>. - * @param exceptions - * the internal names of the method's exception classes (see - * {@link Type#getInternalName() getInternalName}). May be - * <tt>null</tt>. - */ - public MethodNode(final int api, final int access, final String name, - final String desc, final String signature, final String[] exceptions) { - super(api); - this.access = access; - this.name = name; - this.desc = desc; - this.signature = signature; - this.exceptions = new ArrayList<String>(exceptions == null ? 0 - : exceptions.length); - boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0; - if (!isAbstract) { - this.localVariables = new ArrayList<LocalVariableNode>(5); - } - this.tryCatchBlocks = new ArrayList<TryCatchBlockNode>(); - if (exceptions != null) { - this.exceptions.addAll(Arrays.asList(exceptions)); - } - this.instructions = new InsnList(); - } - - // ------------------------------------------------------------------------ - // Implementation of the MethodVisitor abstract class - // ------------------------------------------------------------------------ - - @Override - public void visitParameter(String name, int access) { - if (parameters == null) { - parameters = new ArrayList<ParameterNode>(5); - } - parameters.add(new ParameterNode(name, access)); - } - - @Override - @SuppressWarnings("serial") - public AnnotationVisitor visitAnnotationDefault() { - return new AnnotationNode(new ArrayList<Object>(0) { - @Override - public boolean add(final Object o) { - annotationDefault = o; - return super.add(o); - } + /** + * The method's access flags (see {@link Opcodes}). This field also indicates if the method is + * synthetic and/or deprecated. + */ + public int access; + + /** The method's name. */ + public String name; + + /** The method's descriptor (see {@link Type}). */ + public String desc; + + /** The method's signature. May be {@literal null}. */ + public String signature; + + /** The internal names of the method's exception classes (see {@link Type#getInternalName()}). */ + public List<String> exceptions; + + /** The method parameter info (access flags and name). */ + public List<ParameterNode> parameters; + + /** The runtime visible annotations of this method. May be {@literal null}. */ + public List<AnnotationNode> visibleAnnotations; + + /** The runtime invisible annotations of this method. May be {@literal null}. */ + public List<AnnotationNode> invisibleAnnotations; + + /** The runtime visible type annotations of this method. May be {@literal null}. */ + public List<TypeAnnotationNode> visibleTypeAnnotations; + + /** The runtime invisible type annotations of this method. May be {@literal null}. */ + public List<TypeAnnotationNode> invisibleTypeAnnotations; + + /** The non standard attributes of this method. May be {@literal null}. */ + public List<Attribute> attrs; + + /** + * The default value of this annotation interface method. This field must be a {@link Byte}, + * {@link Boolean}, {@link Character}, {@link Short}, {@link Integer}, {@link Long}, {@link + * Float}, {@link Double}, {@link String} or {@link Type}, or an two elements String array (for + * enumeration values), a {@link AnnotationNode}, or a {@link List} of values of one of the + * preceding types. May be {@literal null}. + */ + public Object annotationDefault; + + /** + * The number of method parameters than can have runtime visible annotations. This number must be + * less or equal than the number of parameter types in the method descriptor (the default value 0 + * indicates that all the parameters described in the method descriptor can have annotations). It + * can be strictly less when a method has synthetic parameters and when these parameters are + * ignored when computing parameter indices for the purpose of parameter annotations (see + * https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18). + */ + public int visibleAnnotableParameterCount; + + /** + * The runtime visible parameter annotations of this method. These lists are lists of {@link + * AnnotationNode} objects. May be {@literal null}. + */ + public List<AnnotationNode>[] visibleParameterAnnotations; + + /** + * The number of method parameters than can have runtime invisible annotations. This number must + * be less or equal than the number of parameter types in the method descriptor (the default value + * 0 indicates that all the parameters described in the method descriptor can have annotations). + * It can be strictly less when a method has synthetic parameters and when these parameters are + * ignored when computing parameter indices for the purpose of parameter annotations (see + * https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18). + */ + public int invisibleAnnotableParameterCount; + + /** + * The runtime invisible parameter annotations of this method. These lists are lists of {@link + * AnnotationNode} objects. May be {@literal null}. + */ + public List<AnnotationNode>[] invisibleParameterAnnotations; + + /** The instructions of this method. */ + public InsnList instructions; + + /** The try catch blocks of this method. */ + public List<TryCatchBlockNode> tryCatchBlocks; + + /** The maximum stack size of this method. */ + public int maxStack; + + /** The maximum number of local variables of this method. */ + public int maxLocals; + + /** The local variables of this method. May be {@literal null} */ + public List<LocalVariableNode> localVariables; + + /** The visible local variable annotations of this method. May be {@literal null} */ + public List<LocalVariableAnnotationNode> visibleLocalVariableAnnotations; + + /** The invisible local variable annotations of this method. May be {@literal null} */ + public List<LocalVariableAnnotationNode> invisibleLocalVariableAnnotations; + + /** Whether the accept method has been called on this object. */ + private boolean visited; + + /** + * Constructs an uninitialized {@link MethodNode}. <i>Subclasses must not use this + * constructor</i>. Instead, they must use the {@link #MethodNode(int)} version. + * + * @throws IllegalStateException If a subclass calls this constructor. + */ + public MethodNode() { + this(Opcodes.ASM7); + if (getClass() != MethodNode.class) { + throw new IllegalStateException(); + } + } + + /** + * Constructs an uninitialized {@link MethodNode}. + * + * @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 MethodNode(final int api) { + super(api); + this.instructions = new InsnList(); + } + + /** + * Constructs a new {@link MethodNode}. <i>Subclasses must not use this constructor</i>. Instead, + * they must use the {@link #MethodNode(int, int, String, String, String, String[])} version. + * + * @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 Type}). + * @param signature the method's signature. May be {@literal null}. + * @param exceptions the internal names of the method's exception classes (see {@link + * Type#getInternalName()}). May be {@literal null}. + * @throws IllegalStateException If a subclass calls this constructor. + */ + public MethodNode( + final int access, + final String name, + final String descriptor, + final String signature, + final String[] exceptions) { + this(Opcodes.ASM7, access, name, descriptor, signature, exceptions); + if (getClass() != MethodNode.class) { + throw new IllegalStateException(); + } + } + + /** + * Constructs a new {@link MethodNode}. + * + * @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 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 Type}). + * @param signature the method's signature. May be {@literal null}. + * @param exceptions the internal names of the method's exception classes (see {@link + * Type#getInternalName()}). May be {@literal null}. + */ + public MethodNode( + final int api, + final int access, + final String name, + final String descriptor, + final String signature, + final String[] exceptions) { + super(api); + this.access = access; + this.name = name; + this.desc = descriptor; + this.signature = signature; + this.exceptions = Util.asArrayList(exceptions); + if ((access & Opcodes.ACC_ABSTRACT) == 0) { + this.localVariables = new ArrayList<LocalVariableNode>(5); + } + this.tryCatchBlocks = new ArrayList<TryCatchBlockNode>(); + this.instructions = new InsnList(); + } + + // ----------------------------------------------------------------------------------------------- + // Implementation of the MethodVisitor abstract class + // ----------------------------------------------------------------------------------------------- + + @Override + public void visitParameter(final String name, final int access) { + if (parameters == null) { + parameters = new ArrayList<ParameterNode>(5); + } + parameters.add(new ParameterNode(name, access)); + } + + @Override + @SuppressWarnings("serial") + public AnnotationVisitor visitAnnotationDefault() { + return new AnnotationNode( + new ArrayList<Object>(0) { + @Override + public boolean add(final Object o) { + annotationDefault = o; + return super.add(o); + } }); - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, - final boolean visible) { - AnnotationNode an = new AnnotationNode(desc); - if (visible) { - if (visibleAnnotations == null) { - visibleAnnotations = new ArrayList<AnnotationNode>(1); - } - visibleAnnotations.add(an); - } else { - if (invisibleAnnotations == null) { - invisibleAnnotations = new ArrayList<AnnotationNode>(1); - } - invisibleAnnotations.add(an); - } - return an; - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); - if (visible) { - if (visibleTypeAnnotations == null) { - visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); - } - visibleTypeAnnotations.add(an); - } else { - if (invisibleTypeAnnotations == null) { - invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); - } - invisibleTypeAnnotations.add(an); - } - return an; - } - - @Override - @SuppressWarnings("unchecked") - public AnnotationVisitor visitParameterAnnotation(final int parameter, - final String desc, final boolean visible) { - AnnotationNode an = new AnnotationNode(desc); - if (visible) { - if (visibleParameterAnnotations == null) { - int params = Type.getArgumentTypes(this.desc).length; - visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params]; - } - if (visibleParameterAnnotations[parameter] == null) { - visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>( - 1); - } - visibleParameterAnnotations[parameter].add(an); - } else { - if (invisibleParameterAnnotations == null) { - int params = Type.getArgumentTypes(this.desc).length; - invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params]; - } - if (invisibleParameterAnnotations[parameter] == null) { - invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>( - 1); - } - invisibleParameterAnnotations[parameter].add(an); - } - return an; - } - - @Override - public void visitAttribute(final Attribute attr) { - if (attrs == null) { - attrs = new ArrayList<Attribute>(1); - } - attrs.add(attr); - } - - @Override - public void visitCode() { - } - - @Override - public void visitFrame(final int type, final int nLocal, - final Object[] local, final int nStack, final Object[] stack) { - instructions.add(new FrameNode(type, nLocal, local == null ? null - : getLabelNodes(local), nStack, stack == null ? null - : getLabelNodes(stack))); - } - - @Override - public void visitInsn(final int opcode) { - instructions.add(new InsnNode(opcode)); - } - - @Override - public void visitIntInsn(final int opcode, final int operand) { - instructions.add(new IntInsnNode(opcode, operand)); - } - - @Override - public void visitVarInsn(final int opcode, final int var) { - instructions.add(new VarInsnNode(opcode, var)); - } - - @Override - public void visitTypeInsn(final int opcode, final String type) { - instructions.add(new TypeInsnNode(opcode, type)); - } - - @Override - public void visitFieldInsn(final int opcode, final String owner, - final String name, final String desc) { - instructions.add(new FieldInsnNode(opcode, owner, name, desc)); - } - - @Deprecated - @Override - public void visitMethodInsn(int opcode, String owner, String name, - String desc) { - if (api >= Opcodes.ASM5) { - super.visitMethodInsn(opcode, owner, name, desc); - return; - } - instructions.add(new MethodInsnNode(opcode, owner, name, desc)); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, - String desc, boolean itf) { - if (api < Opcodes.ASM5) { - super.visitMethodInsn(opcode, owner, name, desc, itf); - return; - } - instructions.add(new MethodInsnNode(opcode, owner, name, desc, itf)); - } - - @Override - public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, - Object... bsmArgs) { - instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs)); - } - - @Override - public void visitJumpInsn(final int opcode, final Label label) { - instructions.add(new JumpInsnNode(opcode, getLabelNode(label))); - } - - @Override - public void visitLabel(final Label label) { - instructions.add(getLabelNode(label)); - } - - @Override - public void visitLdcInsn(final Object cst) { - instructions.add(new LdcInsnNode(cst)); - } - - @Override - public void visitIincInsn(final int var, final int increment) { - instructions.add(new IincInsnNode(var, increment)); - } - - @Override - public void visitTableSwitchInsn(final int min, final int max, - final Label dflt, final Label... labels) { - instructions.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt), - getLabelNodes(labels))); - } - - @Override - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, - final Label[] labels) { - instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys, - getLabelNodes(labels))); - } - - @Override - public void visitMultiANewArrayInsn(final String desc, final int dims) { - instructions.add(new MultiANewArrayInsnNode(desc, dims)); - } - - @Override - public AnnotationVisitor visitInsnAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - // Finds the last real instruction, i.e. the instruction targeted by - // this annotation. - AbstractInsnNode insn = instructions.getLast(); - while (insn.getOpcode() == -1) { - insn = insn.getPrevious(); + } + + @Override + public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { + AnnotationNode annotation = new AnnotationNode(descriptor); + if (visible) { + if (visibleAnnotations == null) { + visibleAnnotations = new ArrayList<AnnotationNode>(1); + } + visibleAnnotations.add(annotation); + } else { + if (invisibleAnnotations == null) { + invisibleAnnotations = new ArrayList<AnnotationNode>(1); + } + invisibleAnnotations.add(annotation); + } + return annotation; + } + + @Override + public AnnotationVisitor visitTypeAnnotation( + final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { + TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor); + if (visible) { + if (visibleTypeAnnotations == null) { + visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); + } + visibleTypeAnnotations.add(typeAnnotation); + } else { + if (invisibleTypeAnnotations == null) { + invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); + } + invisibleTypeAnnotations.add(typeAnnotation); + } + return typeAnnotation; + } + + @Override + public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) { + if (visible) { + visibleAnnotableParameterCount = parameterCount; + } else { + invisibleAnnotableParameterCount = parameterCount; + } + } + + @Override + @SuppressWarnings("unchecked") + public AnnotationVisitor visitParameterAnnotation( + final int parameter, final String descriptor, final boolean visible) { + AnnotationNode annotation = new AnnotationNode(descriptor); + if (visible) { + if (visibleParameterAnnotations == null) { + int params = Type.getArgumentTypes(desc).length; + visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params]; + } + if (visibleParameterAnnotations[parameter] == null) { + visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(1); + } + visibleParameterAnnotations[parameter].add(annotation); + } else { + if (invisibleParameterAnnotations == null) { + int params = Type.getArgumentTypes(desc).length; + invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params]; + } + if (invisibleParameterAnnotations[parameter] == null) { + invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(1); + } + invisibleParameterAnnotations[parameter].add(annotation); + } + return annotation; + } + + @Override + public void visitAttribute(final Attribute attribute) { + if (attrs == null) { + attrs = new ArrayList<Attribute>(1); + } + attrs.add(attribute); + } + + @Override + public void visitCode() { + // Nothing to do. + } + + @Override + public void visitFrame( + final int type, + final int numLocal, + final Object[] local, + final int numStack, + final Object[] stack) { + instructions.add( + new FrameNode( + type, + numLocal, + local == null ? null : getLabelNodes(local), + numStack, + stack == null ? null : getLabelNodes(stack))); + } + + @Override + public void visitInsn(final int opcode) { + instructions.add(new InsnNode(opcode)); + } + + @Override + public void visitIntInsn(final int opcode, final int operand) { + instructions.add(new IntInsnNode(opcode, operand)); + } + + @Override + public void visitVarInsn(final int opcode, final int var) { + instructions.add(new VarInsnNode(opcode, var)); + } + + @Override + public void visitTypeInsn(final int opcode, final String type) { + instructions.add(new TypeInsnNode(opcode, type)); + } + + @Override + public void visitFieldInsn( + final int opcode, final String owner, final String name, final String descriptor) { + instructions.add(new FieldInsnNode(opcode, owner, name, descriptor)); + } + + /** + * Deprecated. + * + * @deprecated use {@link #visitMethodInsn(int, String, String, String, boolean)} instead. + */ + @Deprecated + @Override + public void visitMethodInsn( + final int opcode, final String owner, final String name, final String descriptor) { + if (api >= Opcodes.ASM5) { + super.visitMethodInsn(opcode, owner, name, descriptor); + return; + } + instructions.add(new MethodInsnNode(opcode, owner, name, descriptor)); + } + + @Override + public void visitMethodInsn( + final int opcode, + final String owner, + final String name, + final String descriptor, + final boolean isInterface) { + if (api < Opcodes.ASM5) { + super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); + return; + } + instructions.add(new MethodInsnNode(opcode, owner, name, descriptor, isInterface)); + } + + @Override + public void visitInvokeDynamicInsn( + final String name, + final String descriptor, + final Handle bootstrapMethodHandle, + final Object... bootstrapMethodArguments) { + instructions.add( + new InvokeDynamicInsnNode( + name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments)); + } + + @Override + public void visitJumpInsn(final int opcode, final Label label) { + instructions.add(new JumpInsnNode(opcode, getLabelNode(label))); + } + + @Override + public void visitLabel(final Label label) { + instructions.add(getLabelNode(label)); + } + + @Override + public void visitLdcInsn(final Object value) { + instructions.add(new LdcInsnNode(value)); + } + + @Override + public void visitIincInsn(final int var, final int increment) { + instructions.add(new IincInsnNode(var, increment)); + } + + @Override + public void visitTableSwitchInsn( + final int min, final int max, final Label dflt, final Label... labels) { + instructions.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt), getLabelNodes(labels))); + } + + @Override + public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { + instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys, getLabelNodes(labels))); + } + + @Override + public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) { + instructions.add(new MultiANewArrayInsnNode(descriptor, numDimensions)); + } + + @Override + public AnnotationVisitor visitInsnAnnotation( + final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { + // Find the last real instruction, i.e. the instruction targeted by this annotation. + AbstractInsnNode currentInsn = instructions.getLast(); + while (currentInsn.getOpcode() == -1) { + currentInsn = currentInsn.getPrevious(); + } + // Add the annotation to this instruction. + TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor); + if (visible) { + if (currentInsn.visibleTypeAnnotations == null) { + currentInsn.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); + } + currentInsn.visibleTypeAnnotations.add(typeAnnotation); + } else { + if (currentInsn.invisibleTypeAnnotations == null) { + currentInsn.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); + } + currentInsn.invisibleTypeAnnotations.add(typeAnnotation); + } + return typeAnnotation; + } + + @Override + public void visitTryCatchBlock( + final Label start, final Label end, final Label handler, final String type) { + tryCatchBlocks.add( + new TryCatchBlockNode(getLabelNode(start), getLabelNode(end), getLabelNode(handler), type)); + } + + @Override + public AnnotationVisitor visitTryCatchAnnotation( + final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) { + TryCatchBlockNode tryCatchBlock = tryCatchBlocks.get((typeRef & 0x00FFFF00) >> 8); + TypeAnnotationNode typeAnnotation = new TypeAnnotationNode(typeRef, typePath, descriptor); + if (visible) { + if (tryCatchBlock.visibleTypeAnnotations == null) { + tryCatchBlock.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); + } + tryCatchBlock.visibleTypeAnnotations.add(typeAnnotation); + } else { + if (tryCatchBlock.invisibleTypeAnnotations == null) { + tryCatchBlock.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>(1); + } + tryCatchBlock.invisibleTypeAnnotations.add(typeAnnotation); + } + return typeAnnotation; + } + + @Override + public void visitLocalVariable( + final String name, + final String descriptor, + final String signature, + final Label start, + final Label end, + final int index) { + localVariables.add( + new LocalVariableNode( + name, descriptor, signature, getLabelNode(start), getLabelNode(end), index)); + } + + @Override + public AnnotationVisitor visitLocalVariableAnnotation( + final int typeRef, + final TypePath typePath, + final Label[] start, + final Label[] end, + final int[] index, + final String descriptor, + final boolean visible) { + LocalVariableAnnotationNode localVariableAnnotation = + new LocalVariableAnnotationNode( + typeRef, typePath, getLabelNodes(start), getLabelNodes(end), index, descriptor); + if (visible) { + if (visibleLocalVariableAnnotations == null) { + visibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>(1); + } + visibleLocalVariableAnnotations.add(localVariableAnnotation); + } else { + if (invisibleLocalVariableAnnotations == null) { + invisibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>(1); + } + invisibleLocalVariableAnnotations.add(localVariableAnnotation); + } + return localVariableAnnotation; + } + + @Override + public void visitLineNumber(final int line, final Label start) { + instructions.add(new LineNumberNode(line, getLabelNode(start))); + } + + @Override + public void visitMaxs(final int maxStack, final int maxLocals) { + this.maxStack = maxStack; + this.maxLocals = maxLocals; + } + + @Override + public void visitEnd() { + // Nothing to do. + } + + /** + * Returns the LabelNode corresponding to the given Label. Creates a new LabelNode if necessary. + * The default implementation of this method uses the {@link Label#info} field to store + * associations between labels and label nodes. + * + * @param label a Label. + * @return the LabelNode corresponding to label. + */ + protected LabelNode getLabelNode(final Label label) { + if (!(label.info instanceof LabelNode)) { + label.info = new LabelNode(); + } + return (LabelNode) label.info; + } + + private LabelNode[] getLabelNodes(final Label[] labels) { + LabelNode[] labelNodes = new LabelNode[labels.length]; + for (int i = 0, n = labels.length; i < n; ++i) { + labelNodes[i] = getLabelNode(labels[i]); + } + return labelNodes; + } + + private Object[] getLabelNodes(final Object[] objects) { + Object[] labelNodes = new Object[objects.length]; + for (int i = 0, n = objects.length; i < n; ++i) { + Object o = objects[i]; + if (o instanceof Label) { + o = getLabelNode((Label) o); + } + labelNodes[i] = o; + } + return labelNodes; + } + + // ----------------------------------------------------------------------------------------------- + // Accept method + // ----------------------------------------------------------------------------------------------- + + /** + * Checks that this method node is compatible with the given ASM API version. This method checks + * that this node, and all its children recursively, do not contain elements that were introduced + * in more recent versions of the ASM API than the given version. + * + * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5}, + * {@link Opcodes#ASM6} or {@link Opcodes#ASM7}. + */ + public void check(final int api) { + if (api == Opcodes.ASM4) { + if (parameters != null && !parameters.isEmpty()) { + throw new UnsupportedClassVersionException(); + } + if (visibleTypeAnnotations != null && !visibleTypeAnnotations.isEmpty()) { + throw new UnsupportedClassVersionException(); + } + if (invisibleTypeAnnotations != null && !invisibleTypeAnnotations.isEmpty()) { + throw new UnsupportedClassVersionException(); + } + if (tryCatchBlocks != null) { + for (int i = tryCatchBlocks.size() - 1; i >= 0; --i) { + TryCatchBlockNode tryCatchBlock = tryCatchBlocks.get(i); + if (tryCatchBlock.visibleTypeAnnotations != null + && !tryCatchBlock.visibleTypeAnnotations.isEmpty()) { + throw new UnsupportedClassVersionException(); + } + if (tryCatchBlock.invisibleTypeAnnotations != null + && !tryCatchBlock.invisibleTypeAnnotations.isEmpty()) { + throw new UnsupportedClassVersionException(); + } } - // Adds the annotation to this instruction. - TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); - if (visible) { - if (insn.visibleTypeAnnotations == null) { - insn.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>( - 1); - } - insn.visibleTypeAnnotations.add(an); - } else { - if (insn.invisibleTypeAnnotations == null) { - insn.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>( - 1); - } - insn.invisibleTypeAnnotations.add(an); + } + for (int i = instructions.size() - 1; i >= 0; --i) { + AbstractInsnNode insn = instructions.get(i); + if (insn.visibleTypeAnnotations != null && !insn.visibleTypeAnnotations.isEmpty()) { + throw new UnsupportedClassVersionException(); } - return an; - } - - @Override - public void visitTryCatchBlock(final Label start, final Label end, - final Label handler, final String type) { - tryCatchBlocks.add(new TryCatchBlockNode(getLabelNode(start), - getLabelNode(end), getLabelNode(handler), type)); - } - - @Override - public AnnotationVisitor visitTryCatchAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - TryCatchBlockNode tcb = tryCatchBlocks.get((typeRef & 0x00FFFF00) >> 8); - TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); - if (visible) { - if (tcb.visibleTypeAnnotations == null) { - tcb.visibleTypeAnnotations = new ArrayList<TypeAnnotationNode>( - 1); - } - tcb.visibleTypeAnnotations.add(an); - } else { - if (tcb.invisibleTypeAnnotations == null) { - tcb.invisibleTypeAnnotations = new ArrayList<TypeAnnotationNode>( - 1); - } - tcb.invisibleTypeAnnotations.add(an); + if (insn.invisibleTypeAnnotations != null && !insn.invisibleTypeAnnotations.isEmpty()) { + throw new UnsupportedClassVersionException(); } - return an; - } - - @Override - public void visitLocalVariable(final String name, final String desc, - final String signature, final Label start, final Label end, - final int index) { - localVariables.add(new LocalVariableNode(name, desc, signature, - getLabelNode(start), getLabelNode(end), index)); - } - - @Override - public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, - TypePath typePath, Label[] start, Label[] end, int[] index, - String desc, boolean visible) { - LocalVariableAnnotationNode an = new LocalVariableAnnotationNode( - typeRef, typePath, getLabelNodes(start), getLabelNodes(end), - index, desc); - if (visible) { - if (visibleLocalVariableAnnotations == null) { - visibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>( - 1); - } - visibleLocalVariableAnnotations.add(an); - } else { - if (invisibleLocalVariableAnnotations == null) { - invisibleLocalVariableAnnotations = new ArrayList<LocalVariableAnnotationNode>( - 1); - } - invisibleLocalVariableAnnotations.add(an); + if (insn instanceof MethodInsnNode) { + boolean isInterface = ((MethodInsnNode) insn).itf; + if (isInterface != (insn.opcode == Opcodes.INVOKEINTERFACE)) { + throw new UnsupportedClassVersionException(); + } + } else if (insn instanceof LdcInsnNode) { + Object value = ((LdcInsnNode) insn).cst; + if (value instanceof Handle + || (value instanceof Type && ((Type) value).getSort() == Type.METHOD)) { + throw new UnsupportedClassVersionException(); + } } - return an; - } - - @Override - public void visitLineNumber(final int line, final Label start) { - instructions.add(new LineNumberNode(line, getLabelNode(start))); - } - - @Override - public void visitMaxs(final int maxStack, final int maxLocals) { - this.maxStack = maxStack; - this.maxLocals = maxLocals; - } - - @Override - public void visitEnd() { - } - - /** - * Returns the LabelNode corresponding to the given Label. Creates a new - * LabelNode if necessary. The default implementation of this method uses - * the {@link Label#info} field to store associations between labels and - * label nodes. - * - * @param l - * a Label. - * @return the LabelNode corresponding to l. - */ - protected LabelNode getLabelNode(final Label l) { - if (!(l.info instanceof LabelNode)) { - l.info = new LabelNode(); + } + if (visibleLocalVariableAnnotations != null && !visibleLocalVariableAnnotations.isEmpty()) { + throw new UnsupportedClassVersionException(); + } + if (invisibleLocalVariableAnnotations != null + && !invisibleLocalVariableAnnotations.isEmpty()) { + throw new UnsupportedClassVersionException(); + } + } + if (api != Opcodes.ASM7) { + for (int i = instructions.size() - 1; i >= 0; --i) { + AbstractInsnNode insn = instructions.get(i); + if (insn instanceof LdcInsnNode) { + Object value = ((LdcInsnNode) insn).cst; + if (value instanceof ConstantDynamic) { + throw new UnsupportedClassVersionException(); + } } - return (LabelNode) l.info; - } - - private LabelNode[] getLabelNodes(final Label[] l) { - LabelNode[] nodes = new LabelNode[l.length]; - for (int i = 0; i < l.length; ++i) { - nodes[i] = getLabelNode(l[i]); + } + } + } + + /** + * Makes the given class visitor visit this method. + * + * @param classVisitor a class visitor. + */ + public void accept(final ClassVisitor classVisitor) { + String[] exceptionsArray = new String[this.exceptions.size()]; + this.exceptions.toArray(exceptionsArray); + MethodVisitor methodVisitor = + classVisitor.visitMethod(access, name, desc, signature, exceptionsArray); + if (methodVisitor != null) { + accept(methodVisitor); + } + } + + /** + * Makes the given method visitor visit this method. + * + * @param methodVisitor a method visitor. + */ + public void accept(final MethodVisitor methodVisitor) { + // Visit the parameters. + if (parameters != null) { + for (int i = 0, n = parameters.size(); i < n; i++) { + parameters.get(i).accept(methodVisitor); + } + } + // Visit the annotations. + if (annotationDefault != null) { + AnnotationVisitor annotationVisitor = methodVisitor.visitAnnotationDefault(); + AnnotationNode.accept(annotationVisitor, null, annotationDefault); + if (annotationVisitor != null) { + annotationVisitor.visitEnd(); + } + } + if (visibleAnnotations != null) { + for (int i = 0, n = visibleAnnotations.size(); i < n; ++i) { + AnnotationNode annotation = visibleAnnotations.get(i); + annotation.accept(methodVisitor.visitAnnotation(annotation.desc, true)); + } + } + if (invisibleAnnotations != null) { + for (int i = 0, n = invisibleAnnotations.size(); i < n; ++i) { + AnnotationNode annotation = invisibleAnnotations.get(i); + annotation.accept(methodVisitor.visitAnnotation(annotation.desc, false)); + } + } + if (visibleTypeAnnotations != null) { + for (int i = 0, n = visibleTypeAnnotations.size(); i < n; ++i) { + TypeAnnotationNode typeAnnotation = visibleTypeAnnotations.get(i); + typeAnnotation.accept( + methodVisitor.visitTypeAnnotation( + typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, true)); + } + } + if (invisibleTypeAnnotations != null) { + for (int i = 0, n = invisibleTypeAnnotations.size(); i < n; ++i) { + TypeAnnotationNode typeAnnotation = invisibleTypeAnnotations.get(i); + typeAnnotation.accept( + methodVisitor.visitTypeAnnotation( + typeAnnotation.typeRef, typeAnnotation.typePath, typeAnnotation.desc, false)); + } + } + if (visibleAnnotableParameterCount > 0) { + methodVisitor.visitAnnotableParameterCount(visibleAnnotableParameterCount, true); + } + if (visibleParameterAnnotations != null) { + for (int i = 0, n = visibleParameterAnnotations.length; i < n; ++i) { + List<AnnotationNode> parameterAnnotations = visibleParameterAnnotations[i]; + if (parameterAnnotations == null) { + continue; } - return nodes; - } - - private Object[] getLabelNodes(final Object[] objs) { - Object[] nodes = new Object[objs.length]; - for (int i = 0; i < objs.length; ++i) { - Object o = objs[i]; - if (o instanceof Label) { - o = getLabelNode((Label) o); - } - nodes[i] = o; - } - return nodes; - } - - // ------------------------------------------------------------------------ - // Accept method - // ------------------------------------------------------------------------ - - /** - * Checks that this method node is compatible with the given ASM API - * version. This methods checks that this node, and all its nodes - * recursively, do not contain elements that were introduced in more recent - * versions of the ASM API than the given version. - * - * @param api - * an ASM API version. Must be one of {@link Opcodes#ASM4}, - * {@link Opcodes#ASM5} or {@link Opcodes#ASM6}. - */ - public void check(final int api) { - if (api == Opcodes.ASM4) { - if (visibleTypeAnnotations != null - && visibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - if (invisibleTypeAnnotations != null - && invisibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - int n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size(); - for (int i = 0; i < n; ++i) { - TryCatchBlockNode tcb = tryCatchBlocks.get(i); - if (tcb.visibleTypeAnnotations != null - && tcb.visibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - if (tcb.invisibleTypeAnnotations != null - && tcb.invisibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - } - for (int i = 0; i < instructions.size(); ++i) { - AbstractInsnNode insn = instructions.get(i); - if (insn.visibleTypeAnnotations != null - && insn.visibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - if (insn.invisibleTypeAnnotations != null - && insn.invisibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - if (insn instanceof MethodInsnNode) { - boolean itf = ((MethodInsnNode) insn).itf; - if (itf != (insn.opcode == Opcodes.INVOKEINTERFACE)) { - throw new RuntimeException(); - } - } - } - if (visibleLocalVariableAnnotations != null - && visibleLocalVariableAnnotations.size() > 0) { - throw new RuntimeException(); - } - if (invisibleLocalVariableAnnotations != null - && invisibleLocalVariableAnnotations.size() > 0) { - throw new RuntimeException(); - } + for (int j = 0, m = parameterAnnotations.size(); j < m; ++j) { + AnnotationNode annotation = parameterAnnotations.get(j); + annotation.accept(methodVisitor.visitParameterAnnotation(i, annotation.desc, true)); } + } } - - /** - * Makes the given class visitor visit this method. - * - * @param cv - * a class visitor. - */ - public void accept(final ClassVisitor cv) { - String[] exceptions = new String[this.exceptions.size()]; - this.exceptions.toArray(exceptions); - MethodVisitor mv = cv.visitMethod(access, name, desc, signature, - exceptions); - if (mv != null) { - accept(mv); - } + if (invisibleAnnotableParameterCount > 0) { + methodVisitor.visitAnnotableParameterCount(invisibleAnnotableParameterCount, false); } - - /** - * Makes the given method visitor visit this method. - * - * @param mv - * a method visitor. - */ - public void accept(final MethodVisitor mv) { - // visits the method parameters - int i, j, n; - n = parameters == null ? 0 : parameters.size(); - for (i = 0; i < n; i++) { - ParameterNode parameter = parameters.get(i); - mv.visitParameter(parameter.name, parameter.access); - } - // visits the method attributes - if (annotationDefault != null) { - AnnotationVisitor av = mv.visitAnnotationDefault(); - AnnotationNode.accept(av, null, annotationDefault); - if (av != null) { - av.visitEnd(); - } - } - n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = visibleAnnotations.get(i); - an.accept(mv.visitAnnotation(an.desc, true)); - } - n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = invisibleAnnotations.get(i); - an.accept(mv.visitAnnotation(an.desc, false)); - } - n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size(); - for (i = 0; i < n; ++i) { - TypeAnnotationNode an = visibleTypeAnnotations.get(i); - an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, - true)); - } - n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations - .size(); - for (i = 0; i < n; ++i) { - TypeAnnotationNode an = invisibleTypeAnnotations.get(i); - an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, - false)); + if (invisibleParameterAnnotations != null) { + for (int i = 0, n = invisibleParameterAnnotations.length; i < n; ++i) { + List<AnnotationNode> parameterAnnotations = invisibleParameterAnnotations[i]; + if (parameterAnnotations == null) { + continue; } - n = visibleParameterAnnotations == null ? 0 - : visibleParameterAnnotations.length; - for (i = 0; i < n; ++i) { - List<?> l = visibleParameterAnnotations[i]; - if (l == null) { - continue; - } - for (j = 0; j < l.size(); ++j) { - AnnotationNode an = (AnnotationNode) l.get(j); - an.accept(mv.visitParameterAnnotation(i, an.desc, true)); - } + for (int j = 0, m = parameterAnnotations.size(); j < m; ++j) { + AnnotationNode annotation = parameterAnnotations.get(j); + annotation.accept(methodVisitor.visitParameterAnnotation(i, annotation.desc, false)); } - n = invisibleParameterAnnotations == null ? 0 - : invisibleParameterAnnotations.length; - for (i = 0; i < n; ++i) { - List<?> l = invisibleParameterAnnotations[i]; - if (l == null) { - continue; - } - for (j = 0; j < l.size(); ++j) { - AnnotationNode an = (AnnotationNode) l.get(j); - an.accept(mv.visitParameterAnnotation(i, an.desc, false)); - } + } + } + // Visit the non standard attributes. + if (visited) { + instructions.resetLabels(); + } + if (attrs != null) { + for (int i = 0, n = attrs.size(); i < n; ++i) { + methodVisitor.visitAttribute(attrs.get(i)); + } + } + // Visit the code. + if (instructions.size() > 0) { + methodVisitor.visitCode(); + // Visits the try catch blocks. + if (tryCatchBlocks != null) { + for (int i = 0, n = tryCatchBlocks.size(); i < n; ++i) { + tryCatchBlocks.get(i).updateIndex(i); + tryCatchBlocks.get(i).accept(methodVisitor); } - if (visited) { - instructions.resetLabels(); + } + // Visit the instructions. + instructions.accept(methodVisitor); + // Visits the local variables. + if (localVariables != null) { + for (int i = 0, n = localVariables.size(); i < n; ++i) { + localVariables.get(i).accept(methodVisitor); } - n = attrs == null ? 0 : attrs.size(); - for (i = 0; i < n; ++i) { - mv.visitAttribute(attrs.get(i)); + } + // Visits the local variable annotations. + if (visibleLocalVariableAnnotations != null) { + for (int i = 0, n = visibleLocalVariableAnnotations.size(); i < n; ++i) { + visibleLocalVariableAnnotations.get(i).accept(methodVisitor, true); } - // visits the method's code - if (instructions.size() > 0) { - mv.visitCode(); - // visits try catch blocks - n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size(); - for (i = 0; i < n; ++i) { - tryCatchBlocks.get(i).updateIndex(i); - tryCatchBlocks.get(i).accept(mv); - } - // visits instructions - instructions.accept(mv); - // visits local variables - n = localVariables == null ? 0 : localVariables.size(); - for (i = 0; i < n; ++i) { - localVariables.get(i).accept(mv); - } - // visits local variable annotations - n = visibleLocalVariableAnnotations == null ? 0 - : visibleLocalVariableAnnotations.size(); - for (i = 0; i < n; ++i) { - visibleLocalVariableAnnotations.get(i).accept(mv, true); - } - n = invisibleLocalVariableAnnotations == null ? 0 - : invisibleLocalVariableAnnotations.size(); - for (i = 0; i < n; ++i) { - invisibleLocalVariableAnnotations.get(i).accept(mv, false); - } - // visits maxs - mv.visitMaxs(maxStack, maxLocals); - visited = true; + } + if (invisibleLocalVariableAnnotations != null) { + for (int i = 0, n = invisibleLocalVariableAnnotations.size(); i < n; ++i) { + invisibleLocalVariableAnnotations.get(i).accept(methodVisitor, false); } - mv.visitEnd(); + } + methodVisitor.visitMaxs(maxStack, maxLocals); + visited = true; } + methodVisitor.visitEnd(); + } }
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleExportNode.java ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleExportNode.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleExportNode.java old mode 100644 new mode 100755 index 946872d..c4f6503 --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleExportNode.java +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleExportNode.java @@ -1,82 +1,79 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ +// 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.List; - import org.apache.tapestry5.internal.plastic.asm.ModuleVisitor; /** * A node that represents an exported package with its name and the module that can access to it. - * + * * @author Remi Forax */ public class ModuleExportNode { - /** - * The package name. - */ - public String packaze; - - /** - * The access flags (see {@link org.objectweb.asm.Opcodes}). - * Valid values are {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}. - */ - public int access; - /** - * A list of modules that can access to this exported package. - * May be <tt>null</tt>. - */ - public List<String> modules; + /** The internal name of the exported package. */ + public String packaze; + + /** + * The access flags (see {@link org.apache.tapestry5.internal.plastic.asm.Opcodes}). Valid values are {@code + * ACC_SYNTHETIC} and {@code ACC_MANDATED}. + */ + public int access; + + /** + * The list of modules that can access this exported package, specified with fully qualified names + * (using dots). May be {@literal null}. + */ + public List<String> modules; - /** - * Constructs a new {@link ModuleExportNode}. - * - * @param packaze - * the parameter's name. - * @param modules - * a list of modules that can access to this exported package. - */ - public ModuleExportNode(final String packaze, final int access, final List<String> modules) { - this.packaze = packaze; - this.access = access; - this.modules = modules; - } + /** + * Constructs a new {@link ModuleExportNode}. + * + * @param packaze the internal name of the exported package. + * @param access the package access flags, one or more of {@code ACC_SYNTHETIC} and {@code + * ACC_MANDATED}. + * @param modules a list of modules that can access this exported package, specified with fully + * qualified names (using dots). + */ + public ModuleExportNode(final String packaze, final int access, final List<String> modules) { + this.packaze = packaze; + this.access = access; + this.modules = modules; + } - /** - * Makes the given module visitor visit this export declaration. - * - * @param mv - * a module visitor. - */ - public void accept(final ModuleVisitor mv) { - mv.visitExport(packaze, access, (modules == null) ? null : modules.toArray(new String[0])); - } + /** + * Makes the given module visitor visit this export declaration. + * + * @param moduleVisitor a module visitor. + */ + public void accept(final ModuleVisitor moduleVisitor) { + moduleVisitor.visitExport( + packaze, access, modules == null ? null : modules.toArray(new String[0])); + } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/1c71aec7/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleNode.java ---------------------------------------------------------------------- diff --git a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleNode.java b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleNode.java old mode 100644 new mode 100755 index e76dbf1..fe05259 --- a/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleNode.java +++ b/plastic/src/external/java/org/apache/tapestry5/internal/plastic/asm/tree/ModuleNode.java @@ -1,115 +1,116 @@ -/*** - * 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 org.apache.tapestry5.internal.plastic.asm.ClassVisitor; import org.apache.tapestry5.internal.plastic.asm.ModuleVisitor; import org.apache.tapestry5.internal.plastic.asm.Opcodes; /** * A node that represents a module declaration. - * + * * @author Remi Forax */ public class ModuleNode extends ModuleVisitor { - /** - * Module name - */ - public String name; - - /** - * Module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} - * and {@code ACC_MANDATED}. - */ - public int access; - - /** - * Version of the module. - * May be <tt>null</tt>. - */ - public String version; - - /** - * Name of the main class in internal form - * May be <tt>null</tt>. - */ - public String mainClass; - - /** - * A list of packages that are declared by the current module. - * May be <tt>null</tt>. - */ - public List<String> packages; - - /** - * A list of modules can are required by the current module. - * May be <tt>null</tt>. - */ - public List<ModuleRequireNode> requires; - - /** - * A list of packages that are exported by the current module. - * May be <tt>null</tt>. - */ - public List<ModuleExportNode> exports; - - /** - * A list of packages that are opened by the current module. - * May be <tt>null</tt>. - */ - public List<ModuleOpenNode> opens; - - /** - * A list of classes in their internal forms that are used - * as a service by the current module. May be <tt>null</tt>. - */ - public List<String> uses; - - /** - * A list of services along with their implementations provided - * by the current module. May be <tt>null</tt>. - */ - public List<ModuleProvideNode> provides; - - public ModuleNode(final String name, final int access, - final String version) { - super(Opcodes.ASM6); - this.name = name; - this.access = access; - this.version = version; + + /** The fully qualified name (using dots) of this module. */ + public String name; + + /** + * The module's access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code + * ACC_MANDATED}. + */ + public int access; + + /** The version of this module. May be {@literal null}. */ + public String version; + + /** The internal name of the main class of this module. May be {@literal null}. */ + public String mainClass; + + /** The internal name of the packages declared by this module. May be {@literal null}. */ + public List<String> packages; + + /** The dependencies of this module. May be {@literal null}. */ + public List<ModuleRequireNode> requires; + + /** The packages exported by this module. May be {@literal null}. */ + public List<ModuleExportNode> exports; + + /** The packages opened by this module. May be {@literal null}. */ + public List<ModuleOpenNode> opens; + + /** The internal names of the services used by this module. May be {@literal null}. */ + public List<String> uses; + + /** The services provided by this module. May be {@literal null}. */ + public List<ModuleProvideNode> provides; + + /** + * Constructs a {@link ModuleNode}. <i>Subclasses must not use this constructor</i>. Instead, they + * must use the {@link #ModuleNode(int,String,int,String,List,List,List,List,List)} version. + * + * @param name the fully qualified name (using dots) of the module. + * @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code + * ACC_MANDATED}. + * @param version the module version, or {@literal null}. + * @throws IllegalStateException If a subclass calls this constructor. + */ + public ModuleNode(final String name, final int access, final String version) { + super(Opcodes.ASM7); + if (getClass() != ModuleNode.class) { + throw new IllegalStateException(); } - - public ModuleNode(final int api, + this.name = name; + this.access = access; + this.version = version; + } + + // TODO(forax): why is there no 'mainClass' and 'packages' parameters in this constructor? + /** + * Constructs a {@link ModuleNode}. + * + * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM6} + * or {@link Opcodes#ASM7}. + * @param name the fully qualified name (using dots) of the module. + * @param access the module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC} and {@code + * ACC_MANDATED}. + * @param version the module version, or {@literal null}. + * @param requires The dependencies of this module. May be {@literal null}. + * @param exports The packages exported by this module. May be {@literal null}. + * @param opens The packages opened by this module. May be {@literal null}. + * @param uses The internal names of the services used by this module. May be {@literal null}. + * @param provides The services provided by this module. May be {@literal null}. + */ + public ModuleNode( + final int api, final String name, final int access, final String version, @@ -118,134 +119,117 @@ public class ModuleNode extends ModuleVisitor { final List<ModuleOpenNode> opens, final List<String> uses, final List<ModuleProvideNode> provides) { - super(api); - this.name = name; - this.access = access; - this.version = version; - this.requires = requires; - this.exports = exports; - this.opens = opens; - this.uses = uses; - this.provides = provides; - if (getClass() != ModuleNode.class) { - throw new IllegalStateException(); - } + super(api); + this.name = name; + this.access = access; + this.version = version; + this.requires = requires; + this.exports = exports; + this.opens = opens; + this.uses = uses; + this.provides = provides; + } + + @Override + public void visitMainClass(final String mainClass) { + this.mainClass = mainClass; + } + + @Override + public void visitPackage(final String packaze) { + if (packages == null) { + packages = new ArrayList<String>(5); } - - @Override - public void visitMainClass(String mainClass) { - this.mainClass = mainClass; + packages.add(packaze); + } + + @Override + public void visitRequire(final String module, final int access, final String version) { + if (requires == null) { + requires = new ArrayList<ModuleRequireNode>(5); + } + requires.add(new ModuleRequireNode(module, access, version)); + } + + @Override + public void visitExport(final String packaze, final int access, final String... modules) { + if (exports == null) { + exports = new ArrayList<ModuleExportNode>(5); } - - @Override - public void visitPackage(String packaze) { - if (packages == null) { - packages = new ArrayList<String>(5); - } - packages.add(packaze); + exports.add(new ModuleExportNode(packaze, access, Util.asArrayList(modules))); + } + + @Override + public void visitOpen(final String packaze, final int access, final String... modules) { + if (opens == null) { + opens = new ArrayList<ModuleOpenNode>(5); + } + opens.add(new ModuleOpenNode(packaze, access, Util.asArrayList(modules))); + } + + @Override + public void visitUse(final String service) { + if (uses == null) { + uses = new ArrayList<String>(5); + } + uses.add(service); + } + + @Override + public void visitProvide(final String service, final String... providers) { + if (provides == null) { + provides = new ArrayList<ModuleProvideNode>(5); + } + provides.add(new ModuleProvideNode(service, Util.asArrayList(providers))); + } + + @Override + public void visitEnd() { + // Nothing to do. + } + + /** + * Makes the given class visitor visit this module. + * + * @param classVisitor a class visitor. + */ + public void accept(final ClassVisitor classVisitor) { + ModuleVisitor moduleVisitor = classVisitor.visitModule(name, access, version); + if (moduleVisitor == null) { + return; } - - @Override - public void visitRequire(String module, int access, String version) { - if (requires == null) { - requires = new ArrayList<ModuleRequireNode>(5); - } - requires.add(new ModuleRequireNode(module, access, version)); + if (mainClass != null) { + moduleVisitor.visitMainClass(mainClass); } - - @Override - public void visitExport(String packaze, int access, String... modules) { - if (exports == null) { - exports = new ArrayList<ModuleExportNode>(5); - } - List<String> moduleList = null; - if (modules != null) { - moduleList = new ArrayList<String>(modules.length); - for (int i = 0; i < modules.length; i++) { - moduleList.add(modules[i]); - } - } - exports.add(new ModuleExportNode(packaze, access, moduleList)); + if (packages != null) { + for (int i = 0, n = packages.size(); i < n; i++) { + moduleVisitor.visitPackage(packages.get(i)); + } } - - @Override - public void visitOpen(String packaze, int access, String... modules) { - if (opens == null) { - opens = new ArrayList<ModuleOpenNode>(5); - } - List<String> moduleList = null; - if (modules != null) { - moduleList = new ArrayList<String>(modules.length); - for (int i = 0; i < modules.length; i++) { - moduleList.add(modules[i]); - } - } - opens.add(new ModuleOpenNode(packaze, access, moduleList)); + if (requires != null) { + for (int i = 0, n = requires.size(); i < n; i++) { + requires.get(i).accept(moduleVisitor); + } } - - @Override - public void visitUse(String service) { - if (uses == null) { - uses = new ArrayList<String>(5); - } - uses.add(service); + if (exports != null) { + for (int i = 0, n = exports.size(); i < n; i++) { + exports.get(i).accept(moduleVisitor); + } } - - @Override - public void visitProvide(String service, String... providers) { - if (provides == null) { - provides = new ArrayList<ModuleProvideNode>(5); - } - ArrayList<String> providerList = - new ArrayList<String>(providers.length); - for (int i = 0; i < providers.length; i++) { - providerList.add(providers[i]); - } - provides.add(new ModuleProvideNode(service, providerList)); + if (opens != null) { + for (int i = 0, n = opens.size(); i < n; i++) { + opens.get(i).accept(moduleVisitor); + } } - - @Override - public void visitEnd() { + if (uses != null) { + for (int i = 0, n = uses.size(); i < n; i++) { + moduleVisitor.visitUse(uses.get(i)); + } } - - public void accept(final ClassVisitor cv) { - ModuleVisitor mv = cv.visitModule(name, access, version); - if (mv == null) { - return; - } - if (mainClass != null) { - mv.visitMainClass(mainClass); - } - if (packages != null) { - for (int i = 0; i < packages.size(); i++) { - mv.visitPackage(packages.get(i)); - } - } - - if (requires != null) { - for (int i = 0; i < requires.size(); i++) { - requires.get(i).accept(mv); - } - } - if (exports != null) { - for (int i = 0; i < exports.size(); i++) { - exports.get(i).accept(mv); - } - } - if (opens != null) { - for (int i = 0; i < opens.size(); i++) { - opens.get(i).accept(mv); - } - } - if (uses != null) { - for (int i = 0; i < uses.size(); i++) { - mv.visitUse(uses.get(i)); - } - } - if (provides != null) { - for (int i = 0; i < provides.size(); i++) { - provides.get(i).accept(mv); - } - } + if (provides != null) { + for (int i = 0, n = provides.size(); i < n; i++) { + provides.get(i).accept(moduleVisitor); + } } + } }