1/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2 *
3 * This program and the accompanying materials are made available under
4 * the terms of the Common Public License v1.0 which accompanies this distribution,
5 * and is available at http://www.eclipse.org/legal/cpl-v10.html
6 *
7 * $Id: IConstantCollection.java,v 1.1.1.1 2004/05/09 16:57:46 vlad_r Exp $
8 */
9package com.vladium.jcd.cls;
10
11import com.vladium.jcd.cls.constant.*;
12import com.vladium.jcd.compiler.IClassFormatOutput;
13
14// ----------------------------------------------------------------------------
15/**
16 * An abstraction of constant pool in .class format. This interface disallows
17 * any pool mutation that invalidates already existing pool indices.
18 *
19 * @author (C) 2001, Vlad Roubtsov
20 */
21public
22interface IConstantCollection extends Cloneable, IClassFormatOutput
23{
24    // public: ................................................................
25
26    /**
27     * A custom fail-fast iterator class returned by {@link IConstantCollection#iterator()}.
28     * It allows iterating over all entries in a way that steps over all
29     * 'invalid' inner slots (extra slots consumed by CONSTANT_Long and
30     * CONSTANT_Double entries).
31     */
32    interface IConstantIterator
33    {
34        /**
35         * Returns the next entry slot index.
36         *
37         * @return int next valid slot index [always positive for a valid slot;
38         * -1 when the enumeration is exhausted]
39         */
40        public int nextIndex ();
41
42        /**
43         * Returns the next entry. This is a convenience method for doing
44         * get(nextIndex()) and avoiding index bound violation exceptions.
45         *
46         * @return CONSTANT_info next valid entry [null when the enumeration is
47         * exhausted]
48         */
49        public CONSTANT_info nextConstant ();
50
51        /**
52         * A convenience method that is equivalent to {@link IConstantCollection#set}
53         * and replaces the entry that was visited last without invalidating
54         * the iterator.
55         */
56        CONSTANT_info set (CONSTANT_info constant);
57
58    } // end of nested interface
59
60
61    /**
62     * A simple interface to express custom semantics of constant equality.
63     *
64     * @see IConstantCollection#find(int, IConstantComparator)
65     */
66    interface IConstantComparator
67    {
68        boolean equals (CONSTANT_info constant);
69
70    } // end of nested interface
71
72
73    // ACCESSORS:
74
75    /**
76     * Returns a CONSTANT_info at a given pool index. Note that 'index' is
77     * 1-based [the way an index would be embedded in bytecode instructions].
78     * Note that because CONSTANT_Long and CONSTANT_Double entries occupy
79     * two consequitive index slots certain index values inside the valid range
80     * can be invalid; use {@link #iterator()} to iterate only over valid entries
81     * in a transparent fashion.
82     *
83     * @param index constant pool index [must be in [1, size()] range]
84     * @return CONSTANT_info constant pool entry at this index [never null]
85     *
86     * @throws IllegalStateException if an attempt is made to reference
87     * an invalid slot index
88     * @throws IndexOutOfBoundsException if an attempt is made to reference
89     * a slot outside of the valid range
90     */
91    CONSTANT_info get (int index);
92
93    /**
94     * Returns a fail-fast iterator over all valid entries in the pool. The
95     * resulting object would be invalidated by simultaneous mutation to the
96     * underlying collection pool.
97     *
98     * @return IConstantIterator iterator over all entries in the collection [never null]
99     */
100    IConstantIterator iterator ();
101
102    /**
103     * Searches the pool for a matching constant of given type with equality
104     * semantics expressed by 'comparator'. This method guarantees that
105     * when comparator.equals(c) is called c.type() is 'type'. The cost is
106     * O(pool size). When multiple matches exist, the location of the first one
107     * found will be returned (chosen in some indeterministic way).
108     *
109     * @param type type of constants to filter by [not validated]
110     * @param comparator [may not be null]
111     * @return index of the first found entry [-1 if not found]
112     *
113     * @throws IllegalArgumentException if 'comparator' is null
114     */
115    int find (int type, IConstantComparator comparator);
116
117    /**
118     * Convenience method that can lookup CONSTANT_Utf8 entries in O(1) time
119     * on average. Note that .class format does not guarantee that all such
120     * entries are not duplicated in the pool. When multiple matches exist, the
121     * location of the first one found will be returned (chosen in some
122     * indeterministic way).
123     *
124     * @param value string value on which to match [may not be null]
125     * @return index of the first found entry [-1 if not found]
126     *
127     * @throws IllegalArgumentException if 'value' is null
128     */
129    int findCONSTANT_Utf8 (String value);
130
131    /**
132     * Returns the number of CONSTANT_info entries in this collection.
133     *
134     * @return the number of constants in this pool [can be 0]
135     */
136    int size ();
137
138    // Cloneable: adjust the access level of Object.clone():
139    Object clone ();
140
141    // Visitor:
142    void accept (IClassDefVisitor visitor, Object ctx);
143
144
145    // MUTATORS:
146
147    /**
148     * Appends 'constant' to the end of the collection. No duplicate checks
149     * are made.
150     *
151     * @param constant new constant [may not be null; input unchecked]
152     * @return the pool index of the newly added entry [always positive]
153     */
154    int add (CONSTANT_info constant);
155
156    /**
157     * Replaces an existing constant pool entry. A replacement can be made only
158     * for a constant of the same width as the constant currently occupying the
159     * slot.
160     *
161     * @param index constant pool index [must be in [1, size()] range]
162     * @param constant new entry to set [may not be null; input unchecked]
163     * @return CONSTANT_info previous contents at this pool index [never null]
164     *
165     * @throws IllegalArgumentException if the new constant's width is different
166     * from the current entry's
167     * @throws IllegalStateException if an attempt is made to reference
168     * an invalid slot index [see {@link #get(int)}]
169     * @throws IndexOutOfBoundsException if an attempt is made to reference
170     * a slot outside of the valid range
171     */
172    CONSTANT_info set (int index, CONSTANT_info constant);
173
174} // end of interface
175// ----------------------------------------------------------------------------
176