1674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/***
2674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * ASM: a very small and fast Java bytecode manipulation framework
3674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Copyright (c) 2000-2007 INRIA, France Telecom
4674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * All rights reserved.
5674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *
6674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Redistribution and use in source and binary forms, with or without
7674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * modification, are permitted provided that the following conditions
8674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * are met:
9674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 1. Redistributions of source code must retain the above copyright
10674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *    notice, this list of conditions and the following disclaimer.
11674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 2. Redistributions in binary form must reproduce the above copyright
12674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *    notice, this list of conditions and the following disclaimer in the
13674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *    documentation and/or other materials provided with the distribution.
14674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 3. Neither the name of the copyright holders nor the names of its
15674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *    contributors may be used to endorse or promote products derived from
16674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *    this software without specific prior written permission.
17674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *
18674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * THE POSSIBILITY OF SUCH DAMAGE.
29674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */
30674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpackage org.mockito.asm.tree;
31674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
32674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport java.util.ArrayList;
33674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport java.util.List;
34674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
35674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.AnnotationVisitor;
36674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
37674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/**
38674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * A node that represents an annotationn.
39674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *
40674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @author Eric Bruneton
41674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */
42674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpublic class AnnotationNode implements AnnotationVisitor {
43674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
44674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
45674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * The class descriptor of the annotation class.
46674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
47674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public String desc;
48674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
49674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
50674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * The name value pairs of this annotation. Each name value pair is stored
51674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * as two consecutive elements in the list. The name is a {@link String},
52674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * and the value may be a {@link Byte}, {@link Boolean}, {@link Character},
53674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * {@link Short}, {@link Integer}, {@link Long}, {@link Float},
54674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * {@link Double}, {@link String} or {@link org.mockito.asm.Type}, or an
55674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * two elements String array (for enumeration values), a
56674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * {@link AnnotationNode}, or a {@link List} of values of one of the
57674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * preceding types. The list may be <tt>null</tt> if there is no name
58674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * value pair.
59674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
60674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public List values;
61674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
62674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
63674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Constructs a new {@link AnnotationNode}.
64674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
65674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param desc the class descriptor of the annotation class.
66674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
67674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public AnnotationNode(final String desc) {
68674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        this.desc = desc;
69674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
70674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
71674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
72674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Constructs a new {@link AnnotationNode} to visit an array value.
73674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
74674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param values where the visited values must be stored.
75674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
76674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    AnnotationNode(final List values) {
77674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        this.values = values;
78674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
79674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
80674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    // ------------------------------------------------------------------------
81674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    // Implementation of the AnnotationVisitor interface
82674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    // ------------------------------------------------------------------------
83674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
84674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public void visit(final String name, final Object value) {
85674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (values == null) {
86674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            values = new ArrayList(this.desc != null ? 2 : 1);
87674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
88674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (this.desc != null) {
89674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            values.add(name);
90674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
91674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        values.add(value);
92674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
93674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
94674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public void visitEnum(
95674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        final String name,
96674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        final String desc,
97674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        final String value)
98674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    {
99674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (values == null) {
100674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            values = new ArrayList(this.desc != null ? 2 : 1);
101674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
102674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (this.desc != null) {
103674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            values.add(name);
104674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
105674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        values.add(new String[] { desc, value });
106674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
107674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
108674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public AnnotationVisitor visitAnnotation(
109674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        final String name,
110674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        final String desc)
111674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    {
112674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (values == null) {
113674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            values = new ArrayList(this.desc != null ? 2 : 1);
114674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
115674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (this.desc != null) {
116674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            values.add(name);
117674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
118674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        AnnotationNode annotation = new AnnotationNode(desc);
119674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        values.add(annotation);
120674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return annotation;
121674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
122674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
123674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public AnnotationVisitor visitArray(final String name) {
124674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (values == null) {
125674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            values = new ArrayList(this.desc != null ? 2 : 1);
126674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
127674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (this.desc != null) {
128674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            values.add(name);
129674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
130674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        List array = new ArrayList();
131674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        values.add(array);
132674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return new AnnotationNode(array);
133674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
134674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
135674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public void visitEnd() {
136674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
137674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
138674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    // ------------------------------------------------------------------------
139674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    // Accept methods
140674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    // ------------------------------------------------------------------------
141674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
142674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
143674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Makes the given visitor visit this annotation.
144674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
145674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param av an annotation visitor. Maybe <tt>null</tt>.
146674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
147674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public void accept(final AnnotationVisitor av) {
148674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (av != null) {
149674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            if (values != null) {
150674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                for (int i = 0; i < values.size(); i += 2) {
151674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    String name = (String) values.get(i);
152674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    Object value = values.get(i + 1);
153674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    accept(av, name, value);
154674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                }
155674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
156674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            av.visitEnd();
157674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
158674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
159674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
160674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    /**
161674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * Makes the given visitor visit a given annotation value.
162674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     *
163674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param av an annotation visitor. Maybe <tt>null</tt>.
164674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param name the value name.
165674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     * @param value the actual value.
166674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen     */
167674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    static void accept(
168674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        final AnnotationVisitor av,
169674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        final String name,
170674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        final Object value)
171674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    {
172674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (av != null) {
173674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            if (value instanceof String[]) {
174674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                String[] typeconst = (String[]) value;
175674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                av.visitEnum(name, typeconst[0], typeconst[1]);
176674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            } else if (value instanceof AnnotationNode) {
177674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                AnnotationNode an = (AnnotationNode) value;
178674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                an.accept(av.visitAnnotation(name, an.desc));
179674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            } else if (value instanceof List) {
180674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                AnnotationVisitor v = av.visitArray(name);
181674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                List array = (List) value;
182674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                for (int j = 0; j < array.size(); ++j) {
183674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                    accept(v, null, array.get(j));
184674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                }
185674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                v.visitEnd();
186674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            } else {
187674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                av.visit(name, value);
188674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
189674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
190674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
191674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen}
192