1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/*
2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2007 The Android Open Source Project
3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *
4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License.
6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at
7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *
8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *
10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software
11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and
14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License.
15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */
16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.dex.file;
18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.dex.SizeOf;
20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.annotation.Annotations;
21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.annotation.AnnotationsList;
22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.code.AccessFlags;
23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.Constant;
24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.CstArray;
25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.CstFieldRef;
26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.CstMethodRef;
27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.CstString;
28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.CstType;
29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.type.StdTypeList;
30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.type.TypeList;
31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.AnnotatedOutput;
32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.Hex;
33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.Writers;
34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.io.PrintWriter;
36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.io.Writer;
37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.ArrayList;
38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/**
40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Representation of a Dalvik class, which is basically a set of
41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * members (fields or methods) along with a few more pieces of
42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * information.
43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */
44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class ClassDefItem extends IndexedItem {
45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /** {@code non-null;} type constant for this class */
47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private final CstType thisClass;
48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /** access flags */
50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private final int accessFlags;
51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@code null-ok;} superclass or {@code null} if this class is a/the
54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * root class
55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private final CstType superclass;
57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /** {@code null-ok;} list of implemented interfaces */
59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private TypeListItem interfaces;
60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /** {@code null-ok;} source file name or {@code null} if unknown */
62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private final CstString sourceFile;
63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /** {@code non-null;} associated class data object */
65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private final ClassDataItem classData;
66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@code null-ok;} item wrapper for the static values, initialized
69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * in {@link #addContents}
70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private EncodedArrayItem staticValuesItem;
72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /** {@code non-null;} annotations directory */
74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private AnnotationsDirectoryItem annotationsDirectory;
75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Constructs an instance. Its sets of members and annotations are
78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * initially empty.
79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param thisClass {@code non-null;} type constant for this class
81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param accessFlags access flags
82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param superclass {@code null-ok;} superclass or {@code null} if
83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * this class is a/the root class
84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param interfaces {@code non-null;} list of implemented interfaces
85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param sourceFile {@code null-ok;} source file name or
86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * {@code null} if unknown
87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public ClassDefItem(CstType thisClass, int accessFlags,
89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            CstType superclass, TypeList interfaces, CstString sourceFile) {
90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (thisClass == null) {
91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            throw new NullPointerException("thisClass == null");
92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        /*
95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson         * TODO: Maybe check accessFlags and superclass, at
96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson         * least for easily-checked stuff?
97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson         */
98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (interfaces == null) {
100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            throw new NullPointerException("interfaces == null");
101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.thisClass = thisClass;
104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.accessFlags = accessFlags;
105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.superclass = superclass;
106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.interfaces =
107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            (interfaces.size() == 0) ? null :  new TypeListItem(interfaces);
108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.sourceFile = sourceFile;
109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.classData = new ClassDataItem(thisClass);
110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.staticValuesItem = null;
111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.annotationsDirectory = new AnnotationsDirectoryItem();
112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /** {@inheritDoc} */
115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    @Override
116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public ItemType itemType() {
117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return ItemType.TYPE_CLASS_DEF_ITEM;
118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /** {@inheritDoc} */
121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    @Override
122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public int writeSize() {
123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return SizeOf.CLASS_DEF_ITEM;
124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /** {@inheritDoc} */
127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    @Override
128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void addContents(DexFile file) {
129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        TypeIdsSection typeIds = file.getTypeIds();
130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        MixedItemSection byteData = file.getByteData();
131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        MixedItemSection wordData = file.getWordData();
132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        MixedItemSection typeLists = file.getTypeLists();
133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        StringIdsSection stringIds = file.getStringIds();
134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        typeIds.intern(thisClass);
136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (!classData.isEmpty()) {
138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            MixedItemSection classDataSection = file.getClassData();
139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            classDataSection.add(classData);
140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            CstArray staticValues = classData.getStaticValuesConstant();
142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            if (staticValues != null) {
143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                staticValuesItem =
144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                    byteData.intern(new EncodedArrayItem(staticValues));
145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            }
146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (superclass != null) {
149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            typeIds.intern(superclass);
150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (interfaces != null) {
153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            interfaces = typeLists.intern(interfaces);
154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (sourceFile != null) {
157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            stringIds.intern(sourceFile);
158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (! annotationsDirectory.isEmpty()) {
161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            if (annotationsDirectory.isInternable()) {
162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                annotationsDirectory = wordData.intern(annotationsDirectory);
163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            } else {
164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                wordData.add(annotationsDirectory);
165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            }
166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /** {@inheritDoc} */
170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    @Override
171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void writeTo(DexFile file, AnnotatedOutput out) {
172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        boolean annotates = out.annotates();
173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        TypeIdsSection typeIds = file.getTypeIds();
174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int classIdx = typeIds.indexOf(thisClass);
175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int superIdx = (superclass == null) ? -1 :
176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            typeIds.indexOf(superclass);
177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int interOff = OffsettedItem.getAbsoluteOffsetOr0(interfaces);
178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int annoOff = annotationsDirectory.isEmpty() ? 0 :
179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            annotationsDirectory.getAbsoluteOffset();
180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int sourceFileIdx = (sourceFile == null) ? -1 :
181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            file.getStringIds().indexOf(sourceFile);
182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int dataOff = classData.isEmpty()? 0 : classData.getAbsoluteOffset();
183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int staticValuesOff =
184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            OffsettedItem.getAbsoluteOffsetOr0(staticValuesItem);
185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (annotates) {
187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            out.annotate(0, indexString() + ' ' + thisClass.toHuman());
188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            out.annotate(4, "  class_idx:           " + Hex.u4(classIdx));
189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            out.annotate(4, "  access_flags:        " +
190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                         AccessFlags.classString(accessFlags));
191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            out.annotate(4, "  superclass_idx:      " + Hex.u4(superIdx) +
192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                         " // " + ((superclass == null) ? "<none>" :
193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                          superclass.toHuman()));
194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            out.annotate(4, "  interfaces_off:      " + Hex.u4(interOff));
195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            if (interOff != 0) {
196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                TypeList list = interfaces.getList();
197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                int sz = list.size();
198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                for (int i = 0; i < sz; i++) {
199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                    out.annotate(0, "    " + list.getType(i).toHuman());
200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                }
201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            }
202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            out.annotate(4, "  source_file_idx:     " + Hex.u4(sourceFileIdx) +
203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                         " // " + ((sourceFile == null) ? "<none>" :
204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                          sourceFile.toHuman()));
205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            out.annotate(4, "  annotations_off:     " + Hex.u4(annoOff));
206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            out.annotate(4, "  class_data_off:      " + Hex.u4(dataOff));
207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            out.annotate(4, "  static_values_off:   " +
208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                    Hex.u4(staticValuesOff));
209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        out.writeInt(classIdx);
212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        out.writeInt(accessFlags);
213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        out.writeInt(superIdx);
214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        out.writeInt(interOff);
215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        out.writeInt(sourceFileIdx);
216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        out.writeInt(annoOff);
217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        out.writeInt(dataOff);
218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        out.writeInt(staticValuesOff);
219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the constant corresponding to this class.
223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code non-null;} the constant
225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public CstType getThisClass() {
227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return thisClass;
228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the access flags.
232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
233579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return the access flags
234579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
235579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public int getAccessFlags() {
236579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return accessFlags;
237579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
238579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
239579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
240579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the superclass.
241579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
242579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code null-ok;} the superclass or {@code null} if
243579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * this class is a/the root class
244579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
245579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public CstType getSuperclass() {
246579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return superclass;
247579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
248579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
249579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
250579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the list of interfaces implemented.
251579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
252579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code non-null;} the interfaces list
253579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
254579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public TypeList getInterfaces() {
255579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (interfaces == null) {
256579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            return StdTypeList.EMPTY;
257579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
258579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
259579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return interfaces.getList();
260579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
261579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
262579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
263579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the source file name.
264579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
265579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code null-ok;} the source file name or {@code null} if unknown
266579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
267579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public CstString getSourceFile() {
268579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return sourceFile;
269579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
270579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
271579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
272579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Adds a static field.
273579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
274579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param field {@code non-null;} the field to add
275579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param value {@code null-ok;} initial value for the field, if any
276579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
277579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void addStaticField(EncodedField field, Constant value) {
278579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        classData.addStaticField(field, value);
279579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
280579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
281579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
282579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Adds an instance field.
283579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
284579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param field {@code non-null;} the field to add
285579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
286579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void addInstanceField(EncodedField field) {
287579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        classData.addInstanceField(field);
288579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
289579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
290579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
291579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Adds a direct ({@code static} and/or {@code private}) method.
292579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
293579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param method {@code non-null;} the method to add
294579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
295579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void addDirectMethod(EncodedMethod method) {
296579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        classData.addDirectMethod(method);
297579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
298579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
299579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
300579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Adds a virtual method.
301579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
302579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param method {@code non-null;} the method to add
303579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
304579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void addVirtualMethod(EncodedMethod method) {
305579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        classData.addVirtualMethod(method);
306579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
307579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
308579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
309579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets all the methods in this class. The returned list is not linked
310579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * in any way to the underlying lists contained in this instance, but
311579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * the objects contained in the list are shared.
312579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
313579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code non-null;} list of all methods
314579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
315579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public ArrayList<EncodedMethod> getMethods() {
316579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return classData.getMethods();
317579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
318579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
319579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
320579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Sets the direct annotations on this class. These are annotations
321579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * made on the class, per se, as opposed to on one of its members.
322579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * It is only valid to call this method at most once per instance.
323579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
324579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param annotations {@code non-null;} annotations to set for this class
325579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
326579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void setClassAnnotations(Annotations annotations) {
327579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        annotationsDirectory.setClassAnnotations(annotations);
328579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
329579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
330579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
331579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Adds a field annotations item to this class.
332579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
333579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param field {@code non-null;} field in question
334579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param annotations {@code non-null;} associated annotations to add
335579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
336579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void addFieldAnnotations(CstFieldRef field,
337579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            Annotations annotations) {
338579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        annotationsDirectory.addFieldAnnotations(field, annotations);
339579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
340579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
341579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
342579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Adds a method annotations item to this class.
343579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
344579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param method {@code non-null;} method in question
345579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param annotations {@code non-null;} associated annotations to add
346579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
347579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void addMethodAnnotations(CstMethodRef method,
348579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            Annotations annotations) {
349579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        annotationsDirectory.addMethodAnnotations(method, annotations);
350579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
351579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
352579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
353579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Adds a parameter annotations item to this class.
354579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
355579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param method {@code non-null;} method in question
356579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param list {@code non-null;} associated list of annotation sets to add
357579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
358579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void addParameterAnnotations(CstMethodRef method,
359579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            AnnotationsList list) {
360579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        annotationsDirectory.addParameterAnnotations(method, list);
361579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
362579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
363579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
364579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the method annotations for a given method, if any. This is
365579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * meant for use by debugging / dumping code.
366579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
367579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param method {@code non-null;} the method
368579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code null-ok;} the method annotations, if any
369579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
370579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public Annotations getMethodAnnotations(CstMethodRef method) {
371579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return annotationsDirectory.getMethodAnnotations(method);
372579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
373579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
374579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
375579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the parameter annotations for a given method, if any. This is
376579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * meant for use by debugging / dumping code.
377579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
378579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param method {@code non-null;} the method
379579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code null-ok;} the parameter annotations, if any
380579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
381579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public AnnotationsList getParameterAnnotations(CstMethodRef method) {
382579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return annotationsDirectory.getParameterAnnotations(method);
383579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
384579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
385579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
386579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Prints out the contents of this instance, in a debugging-friendly
387579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * way.
388579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
389579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param out {@code non-null;} where to output to
390579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param verbose whether to be verbose with the output
391579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
392579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void debugPrint(Writer out, boolean verbose) {
393579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        PrintWriter pw = Writers.printWriterFor(out);
394579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
395579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        pw.println(getClass().getName() + " {");
396579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        pw.println("  accessFlags: " + Hex.u2(accessFlags));
397579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        pw.println("  superclass: " + superclass);
398579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        pw.println("  interfaces: " +
399579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                ((interfaces == null) ? "<none>" : interfaces));
400579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        pw.println("  sourceFile: " +
401579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                ((sourceFile == null) ? "<none>" : sourceFile.toQuoted()));
402579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
403579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        classData.debugPrint(out, verbose);
404579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        annotationsDirectory.debugPrint(pw);
405579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
406579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        pw.println("}");
407579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
408579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson}
409