Key.java revision 3062:15bdc18525ff
1/*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package jdk.jshell;
27
28import jdk.jshell.Snippet.Kind;
29import jdk.jshell.Snippet.SubKind;
30
31/**
32 * The Key is unique for a given signature.  Used internal to the implementation
33 * to group signature matched Snippets.  Snippet kinds without a signature
34 * (for example expressions) each have their own UniqueKey.
35 * @author Robert Field
36 */
37abstract class Key {
38
39    /**
40     * The unique index for this Key
41     */
42    private final int index;
43
44    /**
45     * The JShell corresponding to this Key
46     */
47    private final JShell state;
48
49    Key(JShell state) {
50        this.index = state.nextKeyIndex();
51        this.state = state;
52    }
53
54    /**
55     * The unique numeric identifier for the snippet.  Snippets which replace or
56     * redefine existing snippets take on the same key index as the replaced or
57     * redefined snippet.
58     * The index values are monotonically increasing integers.
59     * @return the Key index
60     */
61    int index() { return index; }
62
63    /**
64     * The kind for the key.  Indicates the subinterface of Key.
65     * @return the Kind of the Key
66     */
67    abstract Kind kind();
68
69    /**
70     * For foreign key testing.
71     */
72    JShell state() { return state; }
73
74    /**
75     * Grouping for snippets which persist and influence future code.
76     * They are keyed off at least the name.  They may be Modified/Replaced
77     * with new input and can be dropped (JShell#drop).
78     */
79    static abstract class PersistentKey extends Key {
80
81        private final String name;
82
83        PersistentKey(JShell state, String name) {
84            super(state);
85            this.name = name;
86        }
87        /**
88         * Name of the snippet.
89         *
90         * @return the name of the snippet.
91         */
92        String name() { return name; }
93    }
94
95    /**
96     * Grouping for snippets which reference declarations
97     */
98    static abstract class DeclarationKey extends PersistentKey {
99
100        DeclarationKey(JShell state, String name) {
101            super(state, name);
102        }
103    }
104
105    /**
106     * Key for a class definition Keys of TYPE_DECL. Keyed off class name.
107     */
108    static class TypeDeclKey extends DeclarationKey {
109
110        TypeDeclKey(JShell state, String name) {
111            super(state, name);
112        }
113
114        @Override
115        Kind kind() { return Kind.TYPE_DECL; }
116
117        @Override
118        public String toString() { return "ClassKey(" + name() + ")#" + index(); }
119    }
120
121    /**
122     * Key for a method definition Keys of METHOD. Keyed off method name and
123     * parameter types.
124     */
125    static class MethodKey extends DeclarationKey {
126
127        private final String parameterTypes;
128
129        MethodKey(JShell state, String name, String parameterTypes) {
130            super(state, name);
131            this.parameterTypes = parameterTypes;
132        }
133
134        @Override
135        Kind kind() { return Kind.METHOD; }
136
137        /**
138         * The parameter types of the method. Because of overloading of methods,
139         * the parameter types are part of the key.
140         *
141         * @return a String representation of the parameter types of the method.
142         */
143        String parameterTypes() { return parameterTypes; }
144
145
146        @Override
147        public String toString() { return "MethodKey(" + name() +
148                "(" + parameterTypes() + "))#" + index(); }
149    }
150
151    /**
152     * Key for a variable definition Keys of VARIABLE. Keyed off variable
153     * name.
154     */
155    static class VarKey extends DeclarationKey {
156
157        VarKey(JShell state, String name) {
158            super(state, name);
159        }
160
161        @Override
162        public Kind kind() { return Kind.VAR; }
163
164        @Override
165        public String toString() { return "VariableKey(" + name() + ")#" + index(); }
166    }
167
168    /**
169     * Key for an import. Keys of IMPORT. Keyed off import text and whether
170     * import is static.
171     */
172    static class ImportKey extends PersistentKey {
173
174        private final SubKind snippetKind;
175
176        ImportKey(JShell state, String name,SubKind snippetKind) {
177            super(state, name);
178            this.snippetKind = snippetKind;
179        }
180
181        @Override
182        public Kind kind() { return Kind.IMPORT; }
183
184        /**
185         * Which kind of import.
186         *
187         * @return the appropriate SubKind.
188         */
189        SubKind snippetKind() {
190            return snippetKind;
191        }
192
193
194        @Override
195        public String toString() { return "ImportKey(" + name() + "," +
196                snippetKind + ")#" + index(); }
197    }
198
199    /**
200     * Grouping for snippets which are the key for only one input -- even if the
201     * exactly same entry is made again. The referenced snippets are thus
202     * unmodifiable.
203     */
204    static abstract class UniqueKey extends Key {
205
206        UniqueKey(JShell state) {
207            super(state);
208        }
209    }
210
211    /**
212     * Key for a statement snippet. Keys of STATEMENT. Uniquely keyed, see
213     * UniqueKey.
214     */
215    static class StatementKey extends UniqueKey {
216
217        StatementKey(JShell state) {
218            super(state);
219        }
220
221
222        @Override
223        public Kind kind() {
224            return Kind.STATEMENT;
225        }
226
227        @Override
228        public String toString() { return "StatementKey#" + index(); }
229    }
230
231    /**
232     * Key for an expression. Keys of EXPRESSION. Uniquely keyed, see
233     * UniqueKey.
234     */
235    static class ExpressionKey extends UniqueKey {
236
237        private final String name;
238        private final String typeName;
239
240        ExpressionKey(JShell state, String name, String typeName) {
241            super(state);
242            this.name = name;
243            this.typeName = typeName;
244        }
245
246        @Override
247        public Kind kind() { return Kind.EXPRESSION; }
248
249
250        /**
251         * Variable name which is the value of the expression. Since the
252         * expression is either just an identifier which is a variable or it is
253         * an assignment to a variable, there is always a variable which is the
254         * subject of the expression. All other expression snippets become
255         * temporary variables referenced by a VariableKey.
256         *
257         * @return the name of the variable which is the subject of the
258         * expression.
259         */
260        String name() { return name; }
261
262        /**
263         * Type of the expression
264         *
265         * @return String representation of the type of the expression.
266         */
267        String typeName() { return typeName; }
268
269
270        @Override
271        public String toString() { return "ExpressionKey(" + name() + ")#" + index(); }
272    }
273
274    /**
275     * Key for an erroneous snippet. Keys of ERRONEOUS. Uniquely keyed, see
276     * UniqueKey.
277     */
278    static class ErroneousKey extends UniqueKey {
279
280        ErroneousKey(JShell state) {
281            super(state);
282        }
283
284        @Override
285        Kind kind() { return Kind.ERRONEOUS; }
286
287        @Override
288        public String toString() { return "ErroneousKey#" + index(); }
289    }
290}
291