| /* |
| * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package jdk.jshell; |
| |
| import jdk.jshell.Snippet.Kind; |
| import jdk.jshell.Snippet.SubKind; |
| |
| /** |
| * The Key is unique for a given signature. Used internal to the implementation |
| * to group signature matched Snippets. Snippet kinds without a signature |
| * (for example expressions) each have their own UniqueKey. |
| * @author Robert Field |
| */ |
| abstract class Key { |
| |
| /** |
| * The unique index for this Key |
| */ |
| private final int index; |
| |
| /** |
| * The JShell corresponding to this Key |
| */ |
| private final JShell state; |
| |
| Key(JShell state) { |
| this.index = state.nextKeyIndex(); |
| this.state = state; |
| } |
| |
| /** |
| * The unique numeric identifier for the snippet. Snippets which replace or |
| * redefine existing snippets take on the same key index as the replaced or |
| * redefined snippet. |
| * The index values are monotonically increasing integers. |
| * @return the Key index |
| */ |
| int index() { return index; } |
| |
| /** |
| * The kind for the key. Indicates the subinterface of Key. |
| * @return the Kind of the Key |
| */ |
| abstract Kind kind(); |
| |
| /** |
| * For foreign key testing. |
| */ |
| JShell state() { return state; } |
| |
| /** |
| * Grouping for snippets which persist and influence future code. |
| * They are keyed off at least the name. They may be Modified/Replaced |
| * with new input and can be dropped (JShell#drop). |
| */ |
| static abstract class PersistentKey extends Key { |
| |
| private final String name; |
| |
| PersistentKey(JShell state, String name) { |
| super(state); |
| this.name = name; |
| } |
| /** |
| * Name of the snippet. |
| * |
| * @return the name of the snippet. |
| */ |
| String name() { return name; } |
| } |
| |
| /** |
| * Grouping for snippets which reference declarations |
| */ |
| static abstract class DeclarationKey extends PersistentKey { |
| |
| DeclarationKey(JShell state, String name) { |
| super(state, name); |
| } |
| } |
| |
| /** |
| * Key for a class definition Keys of TYPE_DECL. Keyed off class name. |
| */ |
| static class TypeDeclKey extends DeclarationKey { |
| |
| TypeDeclKey(JShell state, String name) { |
| super(state, name); |
| } |
| |
| @Override |
| Kind kind() { return Kind.TYPE_DECL; } |
| |
| @Override |
| public String toString() { return "ClassKey(" + name() + ")#" + index(); } |
| } |
| |
| /** |
| * Key for a method definition Keys of METHOD. Keyed off method name and |
| * parameter types. |
| */ |
| static class MethodKey extends DeclarationKey { |
| |
| private final String parameterTypes; |
| |
| MethodKey(JShell state, String name, String parameterTypes) { |
| super(state, name); |
| this.parameterTypes = parameterTypes; |
| } |
| |
| @Override |
| Kind kind() { return Kind.METHOD; } |
| |
| /** |
| * The parameter types of the method. Because of overloading of methods, |
| * the parameter types are part of the key. |
| * |
| * @return a String representation of the parameter types of the method. |
| */ |
| String parameterTypes() { return parameterTypes; } |
| |
| |
| @Override |
| public String toString() { return "MethodKey(" + name() + |
| "(" + parameterTypes() + "))#" + index(); } |
| } |
| |
| /** |
| * Key for a variable definition Keys of VARIABLE. Keyed off variable |
| * name. |
| */ |
| static class VarKey extends DeclarationKey { |
| |
| VarKey(JShell state, String name) { |
| super(state, name); |
| } |
| |
| @Override |
| public Kind kind() { return Kind.VAR; } |
| |
| @Override |
| public String toString() { return "VariableKey(" + name() + ")#" + index(); } |
| } |
| |
| /** |
| * Key for an import. Keys of IMPORT. Keyed off import text and whether |
| * import is static. |
| */ |
| static class ImportKey extends PersistentKey { |
| |
| private final SubKind snippetKind; |
| |
| ImportKey(JShell state, String name,SubKind snippetKind) { |
| super(state, name); |
| this.snippetKind = snippetKind; |
| } |
| |
| @Override |
| public Kind kind() { return Kind.IMPORT; } |
| |
| /** |
| * Which kind of import. |
| * |
| * @return the appropriate SubKind. |
| */ |
| SubKind snippetKind() { |
| return snippetKind; |
| } |
| |
| |
| @Override |
| public String toString() { return "ImportKey(" + name() + "," + |
| snippetKind + ")#" + index(); } |
| } |
| |
| /** |
| * Grouping for snippets which are the key for only one input -- even if the |
| * exactly same entry is made again. The referenced snippets are thus |
| * unmodifiable. |
| */ |
| static abstract class UniqueKey extends Key { |
| |
| UniqueKey(JShell state) { |
| super(state); |
| } |
| } |
| |
| /** |
| * Key for a statement snippet. Keys of STATEMENT. Uniquely keyed, see |
| * UniqueKey. |
| */ |
| static class StatementKey extends UniqueKey { |
| |
| StatementKey(JShell state) { |
| super(state); |
| } |
| |
| |
| @Override |
| public Kind kind() { |
| return Kind.STATEMENT; |
| } |
| |
| @Override |
| public String toString() { return "StatementKey#" + index(); } |
| } |
| |
| /** |
| * Key for an expression. Keys of EXPRESSION. Uniquely keyed, see |
| * UniqueKey. |
| */ |
| static class ExpressionKey extends UniqueKey { |
| |
| private final String name; |
| private final String typeName; |
| |
| ExpressionKey(JShell state, String name, String typeName) { |
| super(state); |
| this.name = name; |
| this.typeName = typeName; |
| } |
| |
| @Override |
| public Kind kind() { return Kind.EXPRESSION; } |
| |
| |
| /** |
| * Variable name which is the value of the expression. Since the |
| * expression is either just an identifier which is a variable or it is |
| * an assignment to a variable, there is always a variable which is the |
| * subject of the expression. All other expression snippets become |
| * temporary variables referenced by a VariableKey. |
| * |
| * @return the name of the variable which is the subject of the |
| * expression. |
| */ |
| String name() { return name; } |
| |
| /** |
| * Type of the expression |
| * |
| * @return String representation of the type of the expression. |
| */ |
| String typeName() { return typeName; } |
| |
| |
| @Override |
| public String toString() { return "ExpressionKey(" + name() + ")#" + index(); } |
| } |
| |
| /** |
| * Key for an erroneous snippet. Keys of ERRONEOUS. Uniquely keyed, see |
| * UniqueKey. |
| */ |
| static class ErroneousKey extends UniqueKey { |
| |
| ErroneousKey(JShell state) { |
| super(state); |
| } |
| |
| @Override |
| Kind kind() { return Kind.ERRONEOUS; } |
| |
| @Override |
| public String toString() { return "ErroneousKey#" + index(); } |
| } |
| } |