DirectClassFile.java revision 4c656e4ec2f5c5036dc67fb4034c1e7ff7abf343
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.cf.direct;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.attrib.AttSourceFile;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.cst.ConstantPoolParser;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.Attribute;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.AttributeList;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.ClassFile;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.FieldList;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.MethodList;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.ParseException;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.ParseObserver;
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.StdAttributeList;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.AccessFlags;
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.ConstantPool;
31333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilsonimport com.android.dx.rop.cst.CstString;
32fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.rop.cst.CstType;
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.StdConstantPool;
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.StdTypeList;
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type;
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeList;
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.ByteArray;
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
4199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Class file with info taken from a {@code byte[]} or slice thereof.
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class DirectClassFile implements ClassFile {
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** the expected value of the ClassFile.magic field */
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int CLASS_FILE_MAGIC = 0xcafebabe;
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
4899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * minimum {@code .class} file major version
49de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
50092412605d5d500456e9fff475c90691e668b914Elliott Hughes     * See http://en.wikipedia.org/wiki/Java_class_file for an up-to-date
51092412605d5d500456e9fff475c90691e668b914Elliott Hughes     * list of version numbers. Currently known (taken from that table) are:
52de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
535ca383d7373cf7c54706b8e70d534deee8d2e3addelphinemartin     *     J2SE 7.0 = 51 (0x33 hex),
54092412605d5d500456e9fff475c90691e668b914Elliott Hughes     *     J2SE 6.0 = 50 (0x32 hex),
55092412605d5d500456e9fff475c90691e668b914Elliott Hughes     *     J2SE 5.0 = 49 (0x31 hex),
56092412605d5d500456e9fff475c90691e668b914Elliott Hughes     *     JDK 1.4 = 48 (0x30 hex),
57092412605d5d500456e9fff475c90691e668b914Elliott Hughes     *     JDK 1.3 = 47 (0x2F hex),
58092412605d5d500456e9fff475c90691e668b914Elliott Hughes     *     JDK 1.2 = 46 (0x2E hex),
59092412605d5d500456e9fff475c90691e668b914Elliott Hughes     *     JDK 1.1 = 45 (0x2D hex).
60de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Valid ranges are typically of the form
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * "A.0 through B.C inclusive" where A <= B and C >= 0,
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * which is why we don't have a CLASS_FILE_MIN_MINOR_VERSION.
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int CLASS_FILE_MIN_MAJOR_VERSION = 45;
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
67092412605d5d500456e9fff475c90691e668b914Elliott Hughes    /**
68092412605d5d500456e9fff475c90691e668b914Elliott Hughes     * maximum {@code .class} file major version
69092412605d5d500456e9fff475c90691e668b914Elliott Hughes     *
70092412605d5d500456e9fff475c90691e668b914Elliott Hughes     * Note: if you change this, please change "java.class.version" in System.java.
71092412605d5d500456e9fff475c90691e668b914Elliott Hughes     */
725ca383d7373cf7c54706b8e70d534deee8d2e3addelphinemartin    private static final int CLASS_FILE_MAX_MAJOR_VERSION = 51;
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
7499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** maximum {@code .class} file minor version */
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int CLASS_FILE_MAX_MINOR_VERSION = 0;
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
7899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code non-null;} the file path for the class, excluding any base directory
79de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * specification
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final String filePath;
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
8399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} the bytes of the file */
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final ByteArray bytes;
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * whether to be strict about parsing; if
8899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code false}, this avoids doing checks that only exist
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for purposes of verification (such as magic number matching and
90de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * path-package consistency checking)
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final boolean strictParse;
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
9599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the constant pool; only ever {@code null}
96de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * before the constant pool is successfully parsed
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private StdConstantPool pool;
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
10199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * the class file field {@code access_flags}; will be {@code -1}
102de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * before the file is successfully parsed
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int accessFlags;
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
10799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the class file field {@code this_class},
10899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * interpreted as a type constant; only ever {@code null}
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * before the file is successfully parsed
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private CstType thisClass;
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
11499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the class file field {@code super_class}, interpreted
115de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * as a type constant if non-zero
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private CstType superClass;
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
12099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the class file field {@code interfaces}; only
12199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * ever {@code null} before the file is successfully
122de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * parsed
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private TypeList interfaces;
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
12799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the class file field {@code fields}; only ever
128de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * {@code null} before the file is successfully parsed
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private FieldList fields;
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
13399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the class file field {@code methods}; only ever
134de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * {@code null} before the file is successfully parsed
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private MethodList methods;
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
13999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} the class file field {@code attributes}; only
14099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * ever {@code null} before the file is successfully
141de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     * parsed
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private StdAttributeList attributes;
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
14599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} attribute factory, if any */
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private AttributeFactory attributeFactory;
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
14899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} parse observer, if any */
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private ParseObserver observer;
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
15299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Returns the string form of an object or {@code "(none)"}
15399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * (rather than {@code "null"}) for {@code null}.
154de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
15599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param obj {@code null-ok;} the object to stringify
15699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the appropriate string form
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static String stringOrNone(Object obj) {
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (obj == null) {
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "(none)";
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return obj.toString();
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance.
168de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
16999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param bytes {@code non-null;} the bytes of the file
17099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param filePath {@code non-null;} the file path for the class,
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * excluding any base directory specification
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param strictParse whether to be strict about parsing; if
17399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code false}, this avoids doing checks that only exist
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for purposes of verification (such as magic number matching and
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * path-package consistency checking)
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public DirectClassFile(ByteArray bytes, String filePath,
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                           boolean strictParse) {
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (bytes == null) {
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("bytes == null");
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (filePath == null) {
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("filePath == null");
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.filePath = filePath;
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.bytes = bytes;
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.strictParse = strictParse;
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.accessFlags = -1;
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance.
195de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
19699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param bytes {@code non-null;} the bytes of the file
19799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param filePath {@code non-null;} the file path for the class,
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * excluding any base directory specification
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param strictParse whether to be strict about parsing; if
20099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code false}, this avoids doing checks that only exist
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for purposes of verification (such as magic number matching and
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * path-package consistency checking)
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public DirectClassFile(byte[] bytes, String filePath,
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                           boolean strictParse) {
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this(new ByteArray(bytes), filePath, strictParse);
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the parse observer for this instance.
211de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
21299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param observer {@code null-ok;} the observer
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setObserver(ParseObserver observer) {
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.observer = observer;
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the attribute factory to use.
220de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
22199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param attributeFactory {@code non-null;} the attribute factory
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setAttributeFactory(AttributeFactory attributeFactory) {
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (attributeFactory == null) {
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("attributeFactory == null");
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.attributeFactory = attributeFactory;
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
2324c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche     * Gets the path where this class file is located.
2334c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche     *
2344c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche     * @return {@code non-null;} the filePath
2354c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche     */
2364c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche    public String getFilePath() {
2374c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche      return filePath;
2384c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche    }
2394c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche
2404c656e4ec2f5c5036dc67fb4034c1e7ff7abf343Benoit Lamarche    /**
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the {@link ByteArray} that this instance's data comes from.
242de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
24399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the bytes
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ByteArray getBytes() {
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return bytes;
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMagic() {
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getMagic0();
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMinorVersion() {
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getMinorVersion0();
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMajorVersion() {
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getMajorVersion0();
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getAccessFlags() {
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return accessFlags;
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public CstType getThisClass() {
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return thisClass;
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public CstType getSuperclass() {
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return superClass;
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ConstantPool getConstantPool() {
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return pool;
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public TypeList getInterfaces() {
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToInterfacesIfNecessary();
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return interfaces;
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public FieldList getFields() {
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToEndIfNecessary();
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return fields;
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public MethodList getMethods() {
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToEndIfNecessary();
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return methods;
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public AttributeList getAttributes() {
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parseToEndIfNecessary();
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return attributes;
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
316333201833d506a3accdeac6ceb7caba8d4b95797Jesse Wilson    public CstString getSourceFile() {
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        AttributeList attribs = getAttributes();
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Attribute attSf = attribs.findFirst(AttSourceFile.ATTRIBUTE_NAME);
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (attSf instanceof AttSourceFile) {
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return ((AttSourceFile) attSf).getSourceFile();
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return null;
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs and returns an instance of {@link TypeList} whose
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * data comes from the bytes of this instance, interpreted as a
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * list of constant pool indices for classes, which are in turn
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * translated to type constants. Instance construction will fail
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * if any of the (alleged) indices turn out not to refer to
33399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * constant pool entries of type {@code Class}.
334de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param offset offset into {@link #bytes} for the start of the
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * data
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param size number of elements in the list (not number of bytes)
33899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} an appropriately-constructed class list
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public TypeList makeTypeList(int offset, int size) {
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (size == 0) {
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return StdTypeList.EMPTY;
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (pool == null) {
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalStateException("pool not yet initialized");
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
348de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new DcfTypeList(bytes, offset, size, pool, observer);
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
35399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Gets the class file field {@code magic}, but without doing any
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * checks or parsing first.
355de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the magic value
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMagic0() {
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return bytes.getInt(0);
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
36399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Gets the class file field {@code minor_version}, but
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * without doing any checks or parsing first.
365de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the minor version
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMinorVersion0() {
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return bytes.getUnsignedShort(4);
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
37399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Gets the class file field {@code major_version}, but
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * without doing any checks or parsing first.
375de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the major version
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMajorVersion0() {
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return bytes.getUnsignedShort(6);
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Runs {@link #parse} if it has not yet been run to cover up to
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the interfaces list.
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void parseToInterfacesIfNecessary() {
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (accessFlags == -1) {
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            parse();
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Runs {@link #parse} if it has not yet been run successfully.
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void parseToEndIfNecessary() {
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (attributes == null) {
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            parse();
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Does the parsing, handing exceptions.
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void parse() {
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            parse0();
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ParseException ex) {
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ex.addContext("...while parsing " + filePath);
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw ex;
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (RuntimeException ex) {
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ParseException pe = new ParseException(ex);
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pe.addContext("...while parsing " + filePath);
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw pe;
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sees if the .class file header magic/version are within
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * range.
420de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param magic the value of a classfile "magic" field
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param minorVersion the value of a classfile "minor_version" field
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param majorVersion the value of a classfile "major_version" field
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return true iff the parameters are valid and within range
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean isGoodVersion(int magic, int minorVersion,
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int majorVersion) {
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* Valid version ranges are typically of the form
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * "A.0 through B.C inclusive" where A <= B and C >= 0,
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * which is why we don't have a CLASS_FILE_MIN_MINOR_VERSION.
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (magic == CLASS_FILE_MAGIC && minorVersion >= 0) {
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* Check against max first to handle the case where
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * MIN_MAJOR == MAX_MAJOR.
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (majorVersion == CLASS_FILE_MAX_MAJOR_VERSION) {
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (minorVersion <= CLASS_FILE_MAX_MINOR_VERSION) {
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return true;
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else if (majorVersion < CLASS_FILE_MAX_MAJOR_VERSION &&
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                       majorVersion >= CLASS_FILE_MIN_MAJOR_VERSION) {
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return true;
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Does the actual parsing.
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void parse0() {
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (bytes.size() < 10) {
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new ParseException("severely truncated class file");
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (observer != null) {
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, 0, 0, "begin classfile");
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, 0, 4, "magic: " + Hex.u4(getMagic0()));
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, 4, 2,
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            "minor_version: " + Hex.u2(getMinorVersion0()));
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, 6, 2,
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            "major_version: " + Hex.u2(getMajorVersion0()));
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (strictParse) {
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* Make sure that this looks like a valid class file with a
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * version that we can handle.
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!isGoodVersion(getMagic0(), getMinorVersion0(),
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                               getMajorVersion0())) {
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new ParseException("bad class file magic (" +
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                         Hex.u4(getMagic0()) +
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                         ") or version (" +
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                         Hex.u2(getMajorVersion0()) + "." +
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                         Hex.u2(getMinorVersion0()) + ")");
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ConstantPoolParser cpParser = new ConstantPoolParser(bytes);
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        cpParser.setObserver(observer);
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pool = cpParser.getPool();
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pool.setImmutable();
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int at = cpParser.getEndOffset();
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int accessFlags = bytes.getUnsignedShort(at); // u2 access_flags;
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int cpi = bytes.getUnsignedShort(at + 2); // u2 this_class;
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        thisClass = (CstType) pool.get(cpi);
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        cpi = bytes.getUnsignedShort(at + 4); // u2 super_class;
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        superClass = (CstType) pool.get0Ok(cpi);
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int count = bytes.getUnsignedShort(at + 6); // u2 interfaces_count
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (observer != null) {
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, at, 2,
495de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro                            "access_flags: " +
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            AccessFlags.classString(accessFlags));
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, at + 2, 2, "this_class: " + thisClass);
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, at + 4, 2, "super_class: " +
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            stringOrNone(superClass));
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, at + 6, 2,
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            "interfaces_count: " + Hex.u2(count));
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (count != 0) {
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                observer.parsed(bytes, at + 8, 0, "interfaces:");
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at += 8;
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        interfaces = makeTypeList(at, count);
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at += count * 2;
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (strictParse) {
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Make sure that the file/jar path matches the declared
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * package/class name.
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String thisClassName = thisClass.getClassType().getClassName();
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!(filePath.endsWith(".class") &&
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  filePath.startsWith(thisClassName) &&
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  (filePath.length() == (thisClassName.length() + 6)))) {
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new ParseException("class name (" + thisClassName +
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                         ") does not match path (" +
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                         filePath + ")");
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Only set the instance variable accessFlags here, since
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * that's what signals a successful parse of the first part of
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * the file (through the interfaces list).
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.accessFlags = accessFlags;
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FieldListParser flParser =
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            new FieldListParser(this, thisClass, at, attributeFactory);
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        flParser.setObserver(observer);
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fields = flParser.getList();
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at = flParser.getEndOffset();
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        MethodListParser mlParser =
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            new MethodListParser(this, thisClass, at, attributeFactory);
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mlParser.setObserver(observer);
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methods = mlParser.getList();
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at = mlParser.getEndOffset();
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        AttributeListParser alParser =
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            new AttributeListParser(this, AttributeFactory.CTX_CLASS, at,
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                    attributeFactory);
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        alParser.setObserver(observer);
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        attributes = alParser.getList();
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        attributes.setImmutable();
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        at = alParser.getEndOffset();
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (at != bytes.size()) {
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new ParseException("extra bytes at end of class file, " +
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                     "at offset " + Hex.u4(at));
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (observer != null) {
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            observer.parsed(bytes, at, 0, "end classfile");
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Implementation of {@link TypeList} whose data comes directly
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * from the bytes of an instance of this (outer) class,
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * interpreted as a list of constant pool indices for classes
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * which are in turn returned as type constants. Instance
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * construction will fail if any of the (alleged) indices turn out
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * not to refer to constant pool entries of type
57099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code Class}.
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static class DcfTypeList implements TypeList {
57399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        /** {@code non-null;} array containing the data */
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final ByteArray bytes;
575de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** number of elements in the list (not number of bytes) */
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final int size;
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
57999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        /** {@code non-null;} the constant pool */
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final StdConstantPool pool;
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Constructs an instance.
584de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro         *
58599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param bytes {@code non-null;} original classfile's bytes
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param offset offset into {@link #bytes} for the start of the
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * data
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param size number of elements in the list (not number of bytes)
58999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param pool {@code non-null;} the constant pool to use
59099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param observer {@code null-ok;} parse observer to use, if any
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public DcfTypeList(ByteArray bytes, int offset, int size,
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                StdConstantPool pool, ParseObserver observer) {
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (size < 0) {
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new IllegalArgumentException("size < 0");
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            bytes = bytes.slice(offset, offset + size * 2);
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.bytes = bytes;
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.size = size;
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.pool = pool;
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < size; i++) {
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                offset = i * 2;
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int idx = bytes.getUnsignedShort(offset);
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                CstType type;
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                try {
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    type = (CstType) pool.get(idx);
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } catch (ClassCastException ex) {
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // Translate the exception.
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    throw new RuntimeException("bogus class cpi", ex);
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (observer != null) {
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    observer.parsed(bytes, offset, 2, "  " + type);
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** {@inheritDoc} */
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public boolean isMutable() {
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** {@inheritDoc} */
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public int size() {
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return size;
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** {@inheritDoc} */
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public int getWordCount() {
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // It is the same as size because all elements are classes.
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return size;
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** {@inheritDoc} */
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public Type getType(int n) {
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int idx = bytes.getUnsignedShort(n * 2);
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return ((CstType) pool.get(idx)).getClassType();
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /** {@inheritDoc} */
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public TypeList withAddedType(Type type) {
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new UnsupportedOperationException("unsupported");
644de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        }
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
647