1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/*
2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2008 The Android Open Source Project
3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License");
5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License.
6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at
7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *      http://www.apache.org/licenses/LICENSE-2.0
9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software
11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS,
12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and
14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License.
15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.dex.file;
18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.annotation.Annotation;
20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.annotation.NameValuePair;
21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.Constant;
22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstAnnotation;
23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstArray;
24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstInteger;
25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstKnownNull;
26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstMethodRef;
27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstString;
28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstType;
29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstUtf8;
30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.type.Type;
31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.type.TypeList;
32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.util.ArrayList;
34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport static com.android.dexgen.rop.annotation.AnnotationVisibility.*;
36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/**
38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Utility class for dealing with annotations.
39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class AnnotationUtils {
41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} type for {@code AnnotationDefault} annotations */
42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static final CstType ANNOTATION_DEFAULT_TYPE =
43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        CstType.intern(Type.intern("Ldalvik/annotation/AnnotationDefault;"));
44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} type for {@code EnclosingClass} annotations */
46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static final CstType ENCLOSING_CLASS_TYPE =
47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        CstType.intern(Type.intern("Ldalvik/annotation/EnclosingClass;"));
48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} type for {@code EnclosingMethod} annotations */
50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static final CstType ENCLOSING_METHOD_TYPE =
51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        CstType.intern(Type.intern("Ldalvik/annotation/EnclosingMethod;"));
52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} type for {@code InnerClass} annotations */
54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static final CstType INNER_CLASS_TYPE =
55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        CstType.intern(Type.intern("Ldalvik/annotation/InnerClass;"));
56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} type for {@code MemberClasses} annotations */
58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static final CstType MEMBER_CLASSES_TYPE =
59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        CstType.intern(Type.intern("Ldalvik/annotation/MemberClasses;"));
60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} type for {@code Signature} annotations */
62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static final CstType SIGNATURE_TYPE =
63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        CstType.intern(Type.intern("Ldalvik/annotation/Signature;"));
64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} type for {@code Throws} annotations */
66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static final CstType THROWS_TYPE =
67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        CstType.intern(Type.intern("Ldalvik/annotation/Throws;"));
68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} the UTF-8 constant {@code "accessFlags"} */
70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static final CstUtf8 ACCESS_FLAGS_UTF = new CstUtf8("accessFlags");
71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} the UTF-8 constant {@code "name"} */
73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static final CstUtf8 NAME_UTF = new CstUtf8("name");
74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@code non-null;} the UTF-8 constant {@code "value"} */
76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static final CstUtf8 VALUE_UTF = new CstUtf8("value");
77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * This class is uninstantiable.
80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private AnnotationUtils() {
82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        // This space intentionally left blank.
83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Constructs a standard {@code AnnotationDefault} annotation.
87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param defaults {@code non-null;} the defaults, itself as an annotation
89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the constructed annotation
90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static Annotation makeAnnotationDefault(Annotation defaults) {
92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Annotation result = new Annotation(ANNOTATION_DEFAULT_TYPE, SYSTEM);
93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.put(new NameValuePair(VALUE_UTF, new CstAnnotation(defaults)));
95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.setImmutable();
96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return result;
97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Constructs a standard {@code EnclosingClass} annotation.
101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param clazz {@code non-null;} the enclosing class
103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the annotation
104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static Annotation makeEnclosingClass(CstType clazz) {
106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Annotation result = new Annotation(ENCLOSING_CLASS_TYPE, SYSTEM);
107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.put(new NameValuePair(VALUE_UTF, clazz));
109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.setImmutable();
110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return result;
111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Constructs a standard {@code EnclosingMethod} annotation.
115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param method {@code non-null;} the enclosing method
117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the annotation
118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static Annotation makeEnclosingMethod(CstMethodRef method) {
120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Annotation result = new Annotation(ENCLOSING_METHOD_TYPE, SYSTEM);
121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.put(new NameValuePair(VALUE_UTF, method));
123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.setImmutable();
124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return result;
125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Constructs a standard {@code InnerClass} annotation.
129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param name {@code null-ok;} the original name of the class, or
131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * {@code null} to represent an anonymous class
132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param accessFlags the original access flags
133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the annotation
134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static Annotation makeInnerClass(CstUtf8 name, int accessFlags) {
136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Annotation result = new Annotation(INNER_CLASS_TYPE, SYSTEM);
137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Constant nameCst =
138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            (name != null) ? new CstString(name) : CstKnownNull.THE_ONE;
139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.put(new NameValuePair(NAME_UTF, nameCst));
141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.put(new NameValuePair(ACCESS_FLAGS_UTF,
142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                        CstInteger.make(accessFlags)));
143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.setImmutable();
144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return result;
145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Constructs a standard {@code MemberClasses} annotation.
149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param types {@code non-null;} the list of (the types of) the member classes
151917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the annotation
152917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
153917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static Annotation makeMemberClasses(TypeList types) {
154917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        CstArray array = makeCstArray(types);
155917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Annotation result = new Annotation(MEMBER_CLASSES_TYPE, SYSTEM);
156917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.put(new NameValuePair(VALUE_UTF, array));
157917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.setImmutable();
158917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return result;
159917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
160917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
161917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
162917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Constructs a standard {@code Signature} annotation.
163917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
164917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param signature {@code non-null;} the signature string
165917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the annotation
166917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
167917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static Annotation makeSignature(CstUtf8 signature) {
168917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Annotation result = new Annotation(SIGNATURE_TYPE, SYSTEM);
169917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
170917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        /*
171917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul         * Split the string into pieces that are likely to be common
172917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul         * across many signatures and the rest of the file.
173917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul         */
174917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
175917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        String raw = signature.getString();
176917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int rawLength = raw.length();
177917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        ArrayList<String> pieces = new ArrayList<String>(20);
178917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
179917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int at = 0; at < rawLength; /*at*/) {
180917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            char c = raw.charAt(at);
181917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            int endAt = at + 1;
182917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            if (c == 'L') {
183917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                // Scan to ';' or '<'. Consume ';' but not '<'.
184917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                while (endAt < rawLength) {
185917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                    c = raw.charAt(endAt);
186917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                    if (c == ';') {
187917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                        endAt++;
188917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                        break;
189917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                    } else if (c == '<') {
190917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                        break;
191917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                    }
192917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                    endAt++;
193917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                }
194917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            } else {
195917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                // Scan to 'L' without consuming it.
196917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                while (endAt < rawLength) {
197917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                    c = raw.charAt(endAt);
198917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                    if (c == 'L') {
199917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                        break;
200917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                    }
201917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                    endAt++;
202917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                }
203917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            }
204917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
205917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            pieces.add(raw.substring(at, endAt));
206917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            at = endAt;
207917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
208917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
209917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int size = pieces.size();
210917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        CstArray.List list = new CstArray.List(size);
211917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
212917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < size; i++) {
213917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            list.set(i, new CstString(pieces.get(i)));
214917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
215917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
216917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        list.setImmutable();
217917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
218917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.put(new NameValuePair(VALUE_UTF, new CstArray(list)));
219917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.setImmutable();
220917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return result;
221917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
222917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
223917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
224917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Constructs a standard {@code Throws} annotation.
225917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
226917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param types {@code non-null;} the list of thrown types
227917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the annotation
228917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
229917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public static Annotation makeThrows(TypeList types) {
230917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        CstArray array = makeCstArray(types);
231917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Annotation result = new Annotation(THROWS_TYPE, SYSTEM);
232917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.put(new NameValuePair(VALUE_UTF, array));
233917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        result.setImmutable();
234917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return result;
235917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
236917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
237917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
238917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Converts a {@link TypeList} to a {@link CstArray}.
239917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
240917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param types {@code non-null;} the type list
241917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the corresponding array constant
242917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
243917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static CstArray makeCstArray(TypeList types) {
244917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int size = types.size();
245917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        CstArray.List list = new CstArray.List(size);
246917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
247917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < size; i++) {
248917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            list.set(i, CstType.intern(types.getType(i)));
249917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
250917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
251917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        list.setImmutable();
252917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return new CstArray(list);
253917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
254917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul}
255