001/***
002 * ASM: a very small and fast Java bytecode manipulation framework
003 * Copyright (c) 2000-2011 INRIA, France Telecom
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions
008 * are met:
009 * 1. Redistributions of source code must retain the above copyright
010 *    notice, this list of conditions and the following disclaimer.
011 * 2. Redistributions in binary form must reproduce the above copyright
012 *    notice, this list of conditions and the following disclaimer in the
013 *    documentation and/or other materials provided with the distribution.
014 * 3. Neither the name of the copyright holders nor the names of its
015 *    contributors may be used to endorse or promote products derived from
016 *    this software without specific prior written permission.
017 *
018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
028 * THE POSSIBILITY OF SUCH DAMAGE.
029 */
030
031package io.ebean.enhance.asm.tree;
032
033import io.ebean.enhance.asm.Label;
034import io.ebean.enhance.asm.MethodVisitor;
035import io.ebean.enhance.asm.Opcodes;
036import io.ebean.enhance.asm.TypePath;
037import io.ebean.enhance.asm.TypeReference;
038
039import java.util.ArrayList;
040import java.util.Arrays;
041import java.util.List;
042
043/**
044 * A node that represents a type annotation on a local or resource variable.
045 * 
046 * @author Eric Bruneton
047 */
048public class LocalVariableAnnotationNode extends TypeAnnotationNode {
049
050    /**
051     * The fist instructions corresponding to the continuous ranges that make
052     * the scope of this local variable (inclusive). Must not be <tt>null</tt>.
053     */
054    public List<LabelNode> start;
055
056    /**
057     * The last instructions corresponding to the continuous ranges that make
058     * the scope of this local variable (exclusive). This list must have the
059     * same size as the 'start' list. Must not be <tt>null</tt>.
060     */
061    public List<LabelNode> end;
062
063    /**
064     * The local variable's index in each range. This list must have the same
065     * size as the 'start' list. Must not be <tt>null</tt>.
066     */
067    public List<Integer> index;
068
069    /**
070     * Constructs a new {@link LocalVariableAnnotationNode}. <i>Subclasses must
071     * not use this constructor</i>. Instead, they must use the
072     * {@link #LocalVariableAnnotationNode(int, TypePath, LabelNode[], LabelNode[], int[], String)}
073     * version.
074     * 
075     * @param typeRef
076     *            a reference to the annotated type. See {@link TypeReference}.
077     * @param typePath
078     *            the path to the annotated type argument, wildcard bound, array
079     *            element type, or static inner type within 'typeRef'. May be
080     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
081     * @param start
082     *            the fist instructions corresponding to the continuous ranges
083     *            that make the scope of this local variable (inclusive).
084     * @param end
085     *            the last instructions corresponding to the continuous ranges
086     *            that make the scope of this local variable (exclusive). This
087     *            array must have the same size as the 'start' array.
088     * @param index
089     *            the local variable's index in each range. This array must have
090     *            the same size as the 'start' array.
091     * @param desc
092     *            the class descriptor of the annotation class.
093     */
094    public LocalVariableAnnotationNode(int typeRef, TypePath typePath,
095                                       LabelNode[] start, LabelNode[] end, int[] index, String desc) {
096        this(Opcodes.ASM6, typeRef, typePath, start, end, index, desc);
097    }
098
099    /**
100     * Constructs a new {@link LocalVariableAnnotationNode}.
101     * 
102     * @param api
103     *            the ASM API version implemented by this visitor. Must be one
104     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
105     * @param typeRef
106     *            a reference to the annotated type. See {@link TypeReference}.
107     * @param start
108     *            the fist instructions corresponding to the continuous ranges
109     *            that make the scope of this local variable (inclusive).
110     * @param end
111     *            the last instructions corresponding to the continuous ranges
112     *            that make the scope of this local variable (exclusive). This
113     *            array must have the same size as the 'start' array.
114     * @param index
115     *            the local variable's index in each range. This array must have
116     *            the same size as the 'start' array.
117     * @param typePath
118     *            the path to the annotated type argument, wildcard bound, array
119     *            element type, or static inner type within 'typeRef'. May be
120     *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
121     * @param desc
122     *            the class descriptor of the annotation class.
123     */
124    public LocalVariableAnnotationNode(int api, int typeRef, TypePath typePath,
125                                       LabelNode[] start, LabelNode[] end, int[] index, String desc) {
126        super(api, typeRef, typePath, desc);
127        this.start = new ArrayList<LabelNode>(start.length);
128        this.start.addAll(Arrays.asList(start));
129        this.end = new ArrayList<LabelNode>(end.length);
130        this.end.addAll(Arrays.asList(end));
131        this.index = new ArrayList<Integer>(index.length);
132        for (int i : index) {
133            this.index.add(i);
134        }
135    }
136
137    /**
138     * Makes the given visitor visit this type annotation.
139     * 
140     * @param mv
141     *            the visitor that must visit this annotation.
142     * @param visible
143     *            <tt>true</tt> if the annotation is visible at runtime.
144     */
145    public void accept(final MethodVisitor mv, boolean visible) {
146        Label[] start = new Label[this.start.size()];
147        Label[] end = new Label[this.end.size()];
148        int[] index = new int[this.index.size()];
149        for (int i = 0; i < start.length; ++i) {
150            start[i] = this.start.get(i).getLabel();
151            end[i] = this.end.get(i).getLabel();
152            index[i] = this.index.get(i);
153        }
154        accept(mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
155                index, desc, visible));
156    }
157}