| /* | |
| * Copyright (c) 2015, 2025, 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 java.util.Collection; | |
| import java.util.Collections; | |
| import java.util.List; | |
| /** | |
| * A Snippet represents a snippet of Java source code as passed to | |
| * {@link jdk.jshell.JShell#eval(java.lang.String)}. It is associated only with the | |
| * {@link jdk.jshell.JShell JShell} instance that created it. | |
| * An instance of Snippet (including its subclasses) is immutable: an access to | |
| * any of its methods will always return the same result. | |
| * For information about the current state of the snippet within the JShell | |
| * state engine, query {@code JShell} passing the Snippet. | |
| * <p> | |
| * Because it is immutable, {@code Snippet} (and subclasses) is thread-safe. | |
| * | |
| * @author Robert Field | |
| * @since 9 | |
| * @see jdk.jshell.JShell#status | |
| */ | |
| public abstract class Snippet { | |
| /** | |
| * Describes the general kind of snippet. | |
| * The {@code Kind} is an immutable property of a Snippet. | |
| * It is accessed with {@link jdk.jshell.Snippet#kind()}. | |
| * The {@code Kind} can be used to determine which | |
| * subclass of Snippet it is. For example, | |
| * {@link jdk.jshell.JShell#eval(java.lang.String) eval("int three() { return 3; }")} will | |
| * return a snippet creation event. The {@code Kind} of that Snippet | |
| * will be {@code METHOD}, from which you know that the subclass | |
| * of {@code Snippet} is {@code MethodSnippet} and it can be | |
| * cast as such. | |
| */ | |
| public enum Kind { | |
| /** | |
| * An import declaration: {@code import} ... | |
| * The snippet is an instance of {@link jdk.jshell.ImportSnippet}. | |
| * <P> | |
| * An import can be a single type import | |
| * ({@link jdk.jshell.Snippet.SubKind#SINGLE_TYPE_IMPORT_SUBKIND}), | |
| * a static single import | |
| * ({@link jdk.jshell.Snippet.SubKind#SINGLE_STATIC_IMPORT_SUBKIND}), | |
| * an on-demand type import | |
| * ({@link jdk.jshell.Snippet.SubKind#TYPE_IMPORT_ON_DEMAND_SUBKIND}), | |
| * or a static on-demand type import | |
| * ({@link jdk.jshell.Snippet.SubKind#SINGLE_STATIC_IMPORT_SUBKIND}) -- | |
| * use {@link jdk.jshell.Snippet#subKind()} to distinguish. | |
| * | |
| * <P> | |
| * An import declaration is {@linkplain Kind#isPersistent() persistent}. | |
| * | |
| * @jls 7.5 Import Declarations | |
| */ | |
| IMPORT(true), | |
| /** | |
| * A type declaration. | |
| * Which includes: NormalClassDeclaration, EnumDeclaration, | |
| * NormalInterfaceDeclaration, and AnnotationTypeDeclaration. | |
| * The snippet is an instance of {@link jdk.jshell.TypeDeclSnippet}. | |
| * <P> | |
| * A type declaration may be an interface | |
| * {@link jdk.jshell.Snippet.SubKind#INTERFACE_SUBKIND}, | |
| * classes {@link jdk.jshell.Snippet.SubKind#CLASS_SUBKIND}, enums, and | |
| * annotation interfaces -- see {@link jdk.jshell.Snippet.SubKind} to | |
| * differentiate. | |
| * | |
| * <P> | |
| * A type declaration is {@linkplain Kind#isPersistent() persistent}. | |
| * | |
| * @jls 7.6 Top Level Class and Interface Declarations | |
| */ | |
| TYPE_DECL(true), | |
| /** | |
| * A method declaration. | |
| * The snippet is an instance of {@link jdk.jshell.MethodSnippet}. | |
| * | |
| * <P> | |
| * A method declaration is {@linkplain Kind#isPersistent() persistent}. | |
| * | |
| * @jls 8.4 Method Declarations | |
| */ | |
| METHOD(true), | |
| /** | |
| * One variable declaration. | |
| * Corresponding to one <i>VariableDeclarator</i>. | |
| * The snippet is an instance of {@link jdk.jshell.VarSnippet}. | |
| * <P> | |
| * The variable may be with or without initializer, or be a temporary | |
| * variable representing an expression -- see | |
| * {@link jdk.jshell.Snippet.SubKind}to differentiate. | |
| * | |
| * <P> | |
| * A variable declaration is {@linkplain Kind#isPersistent() persistent}. | |
| * | |
| * @jls 8.3 Field Declarations | |
| */ | |
| VAR(true), | |
| /** | |
| * An expression, with or without side-effects. | |
| * The snippet is an instance of {@link jdk.jshell.ExpressionSnippet}. | |
| * <P> | |
| * The expression is currently either a simple named reference to a | |
| * variable ({@link jdk.jshell.Snippet.SubKind#VAR_VALUE_SUBKIND}) or an | |
| * assignment (both of which have natural referencing | |
| * names) -- see {@link jdk.jshell.Snippet.SubKind} to differentiate. | |
| * All other expression forms (operators, method calls, ...) generate a | |
| * scratch variable and so are instead of the VAR Kind. | |
| * | |
| * @jls 15 Expressions | |
| */ | |
| EXPRESSION(false), | |
| /** | |
| * A statement. | |
| * The snippet is an instance of {@link jdk.jshell.StatementSnippet}. | |
| * | |
| * @jls 14.5 Statements | |
| */ | |
| STATEMENT(false), | |
| /** | |
| * A syntactically incorrect input for which the specific | |
| * kind could not be determined. | |
| * The snippet is an instance of {@link jdk.jshell.ErroneousSnippet}. | |
| */ | |
| ERRONEOUS(false); | |
| private final boolean isPersistent; | |
| Kind(boolean isPersistent) { | |
| this.isPersistent = isPersistent; | |
| } | |
| /** | |
| * Indicates whether this {@code Kind} of Snippet is persistent. Only | |
| * declarations are persistent because they influence future Snippets. | |
| * <p> | |
| * Note that though the {@code Kind} of | |
| * a Snippet may be persistent, that does not mean that the Snippet will | |
| * persist; For example it may be invalid or have been dropped. See: | |
| * {@link jdk.jshell.Snippet.Status#isDefined()}. | |
| * | |
| * @return {@code true} if this {@code Kind} of {@code Snippet} is | |
| * visible to subsequent evaluations; otherwise {@code false} | |
| */ | |
| public boolean isPersistent() { | |
| return isPersistent; | |
| } | |
| } | |
| /** | |
| * The detailed variety of a snippet. This is a sub-classification of the | |
| * Kind. The Kind of a SubKind is accessible with | |
| * {@link jdk.jshell.Snippet.SubKind#kind()}. | |
| */ | |
| public enum SubKind { | |
| /** | |
| * Single-Type-Import Declaration. | |
| * An import declaration of a single type. | |
| * @jls 7.5.1 Single-Type-Import Declarations | |
| */ | |
| SINGLE_TYPE_IMPORT_SUBKIND(Kind.IMPORT), | |
| /** | |
| * Type-Import-on-Demand Declaration. | |
| * A non-static "star" import. | |
| * @jls 7.5.2 Type-Import-on-Demand Declarations | |
| */ | |
| TYPE_IMPORT_ON_DEMAND_SUBKIND(Kind.IMPORT), | |
| /** | |
| * Single-Static-Import Declaration. | |
| * An import of a static member. | |
| * @jls 7.5.3 Single-Static-Import Declarations | |
| */ | |
| SINGLE_STATIC_IMPORT_SUBKIND(Kind.IMPORT), | |
| /** | |
| * Static-Import-on-Demand Declaration. | |
| * A static "star" import of all static members of a named type. | |
| * @jls 7.5.4 Static-Import-on-Demand Declarations | |
| */ | |
| STATIC_IMPORT_ON_DEMAND_SUBKIND(Kind.IMPORT), | |
| /** | |
| * Import Module Declaration. | |
| * An import declaration of a module. | |
| * @jls 7.5.5 Import Module Declarations | |
| * @since 25 | |
| */ | |
| MODULE_IMPORT_SUBKIND(Kind.IMPORT), | |
| /** | |
| * A class declaration. | |
| * A {@code SubKind} of {@link Kind#TYPE_DECL}. | |
| * @jls 8.1 Class Declarations | |
| */ | |
| CLASS_SUBKIND(Kind.TYPE_DECL), | |
| /** | |
| * An interface declaration. | |
| * A {@code SubKind} of {@link Kind#TYPE_DECL}. | |
| * @jls 9.1 Interface Declarations | |
| */ | |
| INTERFACE_SUBKIND(Kind.TYPE_DECL), | |
| /** | |
| * An enum declaration. | |
| * A {@code SubKind} of {@link Kind#TYPE_DECL}. | |
| * @jls 8.9 Enum Classes | |
| */ | |
| ENUM_SUBKIND(Kind.TYPE_DECL), | |
| /** | |
| * A record declaration. | |
| * A {@code SubKind} of {@link Kind#TYPE_DECL}. | |
| * @jls 8.10 Record Classes | |
| * | |
| * @since 17 | |
| */ | |
| RECORD_SUBKIND(Kind.TYPE_DECL), | |
| /** | |
| * An annotation interface declaration. A {@code SubKind} of | |
| * {@link Kind#TYPE_DECL}. | |
| * @jls 9.6 Annotation Interfaces | |
| */ | |
| ANNOTATION_TYPE_SUBKIND(Kind.TYPE_DECL), | |
| /** | |
| * A method. The only {@code SubKind} for {@link Kind#METHOD}. | |
| * @jls 8.4 Method Declarations | |
| */ | |
| METHOD_SUBKIND(Kind.METHOD), | |
| /** | |
| * A variable declaration without initializer. | |
| * A {@code SubKind} of {@link Kind#VAR}. | |
| * @jls 8.3 Field Declarations | |
| */ | |
| VAR_DECLARATION_SUBKIND(Kind.VAR, true, true), | |
| /** | |
| * A variable declaration with an initializer expression. A | |
| * {@code SubKind} of {@link Kind#VAR}. | |
| * @jls 8.3 Field Declarations | |
| */ | |
| VAR_DECLARATION_WITH_INITIALIZER_SUBKIND(Kind.VAR, true, true), | |
| /** | |
| * An expression whose value has been stored in a temporary variable. A | |
| * {@code SubKind} of {@link Kind#VAR}. | |
| * @jls 15 Expressions | |
| */ | |
| TEMP_VAR_EXPRESSION_SUBKIND(Kind.VAR, true, true), | |
| /** | |
| * A simple variable reference expression. A {@code SubKind} of | |
| * {@link Kind#EXPRESSION}. | |
| * @jls 15.11 Field Access Expressions | |
| */ | |
| VAR_VALUE_SUBKIND(Kind.EXPRESSION, true, true), | |
| /** | |
| * An assignment expression. A {@code SubKind} of | |
| * {@link Kind#EXPRESSION}. | |
| * @jls 15.26 Assignment Operators | |
| */ | |
| ASSIGNMENT_SUBKIND(Kind.EXPRESSION, true, true), | |
| /** | |
| * An expression which has not been wrapped in a temporary variable | |
| * (reserved). A {@code SubKind} of {@link Kind#EXPRESSION}. | |
| */ | |
| OTHER_EXPRESSION_SUBKIND(Kind.EXPRESSION, true, true), | |
| /** | |
| * A statement. The only {@code SubKind} for {@link Kind#STATEMENT}. | |
| * @jls 14.5 Statements | |
| */ | |
| STATEMENT_SUBKIND(Kind.STATEMENT, true, false), | |
| /** | |
| * An unknown snippet. The only {@code SubKind} for | |
| * {@link Kind#ERRONEOUS}. | |
| */ | |
| UNKNOWN_SUBKIND(Kind.ERRONEOUS, false, false); | |
| private final boolean isExecutable; | |
| private final boolean hasValue; | |
| private final Kind kind; | |
| SubKind(Kind kind) { | |
| this.kind = kind; | |
| this.isExecutable = false; | |
| this.hasValue = false; | |
| } | |
| SubKind(Kind kind, boolean isExecutable, boolean hasValue) { | |
| this.kind = kind; | |
| this.isExecutable = isExecutable; | |
| this.hasValue = hasValue; | |
| } | |
| /** | |
| * Indicates whether this {@code SubKind} is executable. | |
| * | |
| * @return {@code true} if this {@code SubKind} can | |
| * be executed; otherwise {@code false} | |
| */ | |
| public boolean isExecutable() { | |
| return isExecutable; | |
| } | |
| /** | |
| * Indicates whether this {@code SubKind} is executable and | |
| * is non-{@code void}. | |
| * | |
| * @return {@code true} if this {@code SubKind} has | |
| * a value; otherwise {@code false} | |
| */ | |
| public boolean hasValue() { | |
| return hasValue; | |
| } | |
| /** | |
| * The {@link Snippet.Kind} that corresponds to this {@code SubKind}. | |
| * | |
| * @return the fixed {@code Kind} for this {@code SubKind} | |
| */ | |
| public Kind kind() { | |
| return kind; | |
| } | |
| } | |
| /** | |
| * Describes the current state of a Snippet. | |
| * This is a dynamic property of a Snippet within the JShell state -- | |
| * thus is retrieved with a {@linkplain | |
| * jdk.jshell.JShell#status(jdk.jshell.Snippet) query on {@code JShell}}. | |
| * <p> | |
| * The {@code Status} changes as the state changes. | |
| * For example, creation of another snippet with | |
| * {@link jdk.jshell.JShell#eval(java.lang.String) eval} | |
| * may resolve dependencies of this Snippet (or invalidate those dependencies), or | |
| * {@linkplain jdk.jshell.Snippet.Status#OVERWRITTEN overwrite} | |
| * this Snippet changing its | |
| * {@code Status}. | |
| * <p> | |
| * Important properties associated with {@code Status} are: | |
| * {@link jdk.jshell.Snippet.Status#isDefined()}, if it is visible to other | |
| * existing and new snippets; and | |
| * {@link jdk.jshell.Snippet.Status#isActive()}, if, as the | |
| * JShell state changes, the snippet will update, possibly | |
| * changing {@code Status}. | |
| * An executable Snippet can only be executed if it is in the | |
| * {@link jdk.jshell.Snippet.Status#VALID} {@code Status}. | |
| * @see JShell#status(jdk.jshell.Snippet) | |
| */ | |
| public enum Status { | |
| /** | |
| * The snippet is a valid snippet | |
| * (in the context of current {@code JShell} state). | |
| * Only snippets with {@code VALID} | |
| * {@code Status} can be executed (though not all | |
| * {@code VALID} snippets have executable code). | |
| * <p> | |
| * The snippet is defined | |
| * ({@link Status#isDefined() isDefined() == true}). | |
| * If the snippet is a declaration or import | |
| * ({@link Snippet.Kind#isPersistent()}), | |
| * it is visible to other snippets | |
| * <p> | |
| * The snippet will update as dependents change | |
| * ({@link Status#isActive() isActive() == true}), its | |
| * status could become {@code RECOVERABLE_DEFINED}, {@code RECOVERABLE_NOT_DEFINED}, | |
| * {@code DROPPED}, or {@code OVERWRITTEN}. | |
| */ | |
| VALID(true, true), | |
| /** | |
| * The snippet is a declaration snippet with potentially recoverable | |
| * unresolved references or other issues in its body | |
| * (in the context of current {@code JShell} state). | |
| * Only a {@link jdk.jshell.DeclarationSnippet} can have this | |
| * {@code Status}. | |
| * <p> | |
| * The snippet has a valid signature and it is visible to other | |
| * snippets | |
| * ({@link Status#isDefined() isDefined() == true}) | |
| * and thus can be referenced in existing or new snippets | |
| * but the snippet cannot be executed. | |
| * An {@link UnresolvedReferenceException} will be thrown on an attempt | |
| * to execute it. | |
| * <p> | |
| * The snippet will update as dependents change | |
| * ({@link Status#isActive() isActive() == true}), its | |
| * status could become {@code VALID}, {@code RECOVERABLE_NOT_DEFINED}, | |
| * {@code DROPPED}, or {@code OVERWRITTEN}. | |
| * <p> | |
| * Note: both {@code RECOVERABLE_DEFINED} and {@code RECOVERABLE_NOT_DEFINED} | |
| * indicate potentially recoverable errors, they differ in that, for | |
| * {@code RECOVERABLE_DEFINED}, the snippet is | |
| * {@linkplain Status#isDefined() defined}. | |
| */ | |
| RECOVERABLE_DEFINED(true, true), | |
| /** | |
| * The snippet is a declaration snippet with potentially recoverable | |
| * unresolved references or other issues | |
| * (in the context of current {@code JShell} state). | |
| * Only a {@link jdk.jshell.DeclarationSnippet} can have this | |
| * {@code Status}. | |
| * <p> | |
| * The snippet has an invalid signature or the implementation is | |
| * otherwise unable to define it. | |
| * The snippet it is not visible to other snippets | |
| * ({@link Status#isDefined() isDefined() == false}) | |
| * and thus cannot be referenced or executed. | |
| * <p> | |
| * The snippet will update as dependents change | |
| * ({@link Status#isActive() isActive() == true}), its | |
| * status could become {@code VALID}, {@code RECOVERABLE_DEFINED}, | |
| * {@code DROPPED}, or {@code OVERWRITTEN}. | |
| * <p> | |
| * Note: both {@code RECOVERABLE_DEFINED} and {@code RECOVERABLE_NOT_DEFINED} | |
| * indicate potentially recoverable errors, they differ in that, for | |
| * {@code RECOVERABLE_DEFINED}, the snippet is | |
| * {@linkplain Status#isDefined() defined}. | |
| */ | |
| RECOVERABLE_NOT_DEFINED(true, false), | |
| /** | |
| * The snippet is inactive because of an explicit call to | |
| * the {@link JShell#drop(Snippet)}. | |
| * <p> | |
| * The snippet is not visible to other snippets | |
| * ({@link Status#isDefined() isDefined() == false}) | |
| * and thus cannot be referenced or executed. | |
| * <p> | |
| * The snippet will not update as dependents change | |
| * ({@link Status#isActive() isActive() == false}), its | |
| * {@code Status} will never change again. | |
| */ | |
| DROPPED(false, false), | |
| /** | |
| * The snippet is inactive because it has been replaced by a new | |
| * snippet. This occurs when the new snippet added with | |
| * {@link jdk.jshell.JShell#eval(java.lang.String) eval} matches a previous snippet. | |
| * A {@code TypeDeclSnippet} will match another | |
| * {@code TypeDeclSnippet} if the names match. | |
| * For example {@code class X { }} will overwrite | |
| * {@code class X { int ii; }} or | |
| * {@code interface X { }}. | |
| * A {@code MethodSnippet} will match another | |
| * {@code MethodSnippet} if the names and parameter types | |
| * match. | |
| * For example {@code void m(int a) { }} will overwrite | |
| * {@code int m(int a) { return a+a; }}. | |
| * A {@code VarSnippet} will match another | |
| * {@code VarSnippet} if the names match. | |
| * For example {@code double z;} will overwrite | |
| * {@code long z = 2L;}. | |
| * Only a {@link jdk.jshell.PersistentSnippet} can have this | |
| * {@code Status}. | |
| * <p> | |
| * The snippet is not visible to other snippets | |
| * ({@link Status#isDefined() isDefined() == false}) | |
| * and thus cannot be referenced or executed. | |
| * <p> | |
| * The snippet will not update as dependents change | |
| * ({@link Status#isActive() isActive() == false}), its | |
| * {@code Status} will never change again. | |
| */ | |
| OVERWRITTEN(false, false), | |
| /** | |
| * The snippet is inactive because it failed compilation on initial | |
| * evaluation and it is not capable of becoming valid with further | |
| * changes to the JShell state. | |
| * <p> | |
| * The snippet is not visible to other snippets | |
| * ({@link Status#isDefined() isDefined() == false}) | |
| * and thus cannot be referenced or executed. | |
| * <p> | |
| * The snippet will not update as dependents change | |
| * ({@link Status#isActive() isActive() == false}), its | |
| * {@code Status} will never change again. | |
| */ | |
| REJECTED(false, false), | |
| /** | |
| * The snippet is inactive because it does not yet exist. | |
| * Used only in {@link SnippetEvent#previousStatus()} for new | |
| * snippets. | |
| * {@link jdk.jshell.JShell#status(jdk.jshell.Snippet) JShell.status(Snippet)} | |
| * will never return this {@code Status}. | |
| * <p> | |
| * Vacuously, {@link Status#isDefined() isDefined()} and | |
| * {@link Status#isActive() isActive()} are both defined {@code false}. | |
| */ | |
| NONEXISTENT(false, false); | |
| private final boolean isActive; | |
| private final boolean isDefined; | |
| Status(boolean isActive, boolean isDefined) { | |
| this.isActive = isActive; | |
| this.isDefined = isDefined; | |
| } | |
| /** | |
| * Indicates whether the Snippet is active, that is, | |
| * will a {@linkplain jdk.jshell.PersistentSnippet persistent} | |
| * snippet be re-evaluated when a new | |
| * {@link JShell#eval(java.lang.String) JShell.eval(String)} or | |
| * {@link JShell#drop(jdk.jshell.Snippet) | |
| * JShell.drop(Snippet)} that could change | |
| * its status is invoked. This is more broad than | |
| * {@link Status#isDefined()} since a Snippet which is | |
| * {@link Status#RECOVERABLE_NOT_DEFINED} | |
| * will be updated. | |
| * | |
| * @return {@code true} if the Snippet is active; otherwise {@code false} | |
| */ | |
| public boolean isActive() { | |
| return isActive; | |
| } | |
| /** | |
| * Indicates whether the snippet is currently part of the defined state | |
| * of the JShell. Is it visible to compilation of other snippets? | |
| * @return {@code true} if the Snippet is defined; otherwise | |
| * {@code false} | |
| */ | |
| public boolean isDefined() { | |
| return isDefined; | |
| } | |
| } | |
| static final String UNASSOCIATED_ID = "*UNASSOCIATED*"; | |
| private final Key key; | |
| private final String source; | |
| private final Wrap guts; | |
| final String unitName; | |
| private final SubKind subkind; | |
| private int seq; | |
| private String id; | |
| private OuterWrap outer; | |
| private Status status; | |
| private List<String> unresolved; | |
| private DiagList diagnostics; | |
| private final DiagList syntheticDiags; | |
| Snippet(Key key, String userSource, Wrap guts, String unitName, | |
| SubKind subkind, DiagList syntheticDiags) { | |
| this.key = key; | |
| this.source = userSource; | |
| this.guts = guts; | |
| this.unitName = unitName; | |
| this.subkind = subkind; | |
| this.syntheticDiags = syntheticDiags==null | |
| ? new DiagList() | |
| : syntheticDiags; | |
| this.status = Status.NONEXISTENT; | |
| setSequenceNumber(0); | |
| } | |
| //**** public access **** | |
| /** | |
| * The unique identifier for the snippet. No two active snippets will have | |
| * the same id(). Value of id has no prescribed meaning. The details of | |
| * how the id is generated and the mechanism to change it is documented in | |
| * {@link JShell.Builder#idGenerator(BiFunction)}. | |
| * @return the snippet id string. | |
| */ | |
| public String id() { | |
| return id; | |
| } | |
| /** | |
| * The {@link jdk.jshell.Snippet.Kind} for the snippet. | |
| * Indicates the subclass of Snippet. | |
| * @return the Kind of the snippet | |
| * @see Snippet.Kind | |
| */ | |
| public Kind kind() { | |
| return subkind.kind(); | |
| } | |
| /** | |
| * Return the {@link SubKind} of snippet. | |
| * The SubKind is useful for feedback to users. | |
| * @return the SubKind corresponding to this snippet | |
| */ | |
| public SubKind subKind() { | |
| return subkind; | |
| } | |
| /** | |
| * Return the source code of the snippet. | |
| * @return the source code corresponding to this snippet | |
| */ | |
| public String source() { | |
| return source; | |
| } | |
| @Override | |
| public String toString() { | |
| StringBuilder sb = new StringBuilder(); | |
| sb.append("Snippet:"); | |
| if (key() != null) { | |
| sb.append(key().toString()); | |
| } | |
| sb.append('-'); | |
| sb.append(source); | |
| return sb.toString(); | |
| } | |
| //**** internal access **** | |
| String name() { | |
| return unitName; | |
| } | |
| Key key() { | |
| return key; | |
| } | |
| List<String> unresolved() { | |
| return Collections.unmodifiableList(unresolved); | |
| } | |
| DiagList diagnostics() { | |
| return diagnostics; | |
| } | |
| DiagList syntheticDiags() { | |
| return syntheticDiags; | |
| } | |
| /** | |
| * @return the corralled guts | |
| */ | |
| Wrap corralled() { | |
| return null; | |
| } | |
| Collection<String> declareReferences() { | |
| return null; | |
| } | |
| Collection<String> bodyReferences() { | |
| return null; | |
| } | |
| String importLine(JShell state) { | |
| return ""; | |
| } | |
| void setId(String id) { | |
| this.id = id; | |
| } | |
| final void setSequenceNumber(int seq) { | |
| this.seq = seq; | |
| } | |
| void setOuterWrap(OuterWrap outer) { | |
| this.outer = outer; | |
| } | |
| void setCompilationStatus(Status status, List<String> unresolved, DiagList diagnostics) { | |
| this.status = status; | |
| this.unresolved = unresolved; | |
| this.diagnostics = diagnostics; | |
| } | |
| void setDiagnostics(DiagList diagnostics) { | |
| this.diagnostics = diagnostics; | |
| } | |
| void setFailed(DiagList diagnostics) { | |
| this.seq = -1; | |
| this.outer = null; | |
| this.status = Status.REJECTED; | |
| this.unresolved = Collections.emptyList(); | |
| this.diagnostics = diagnostics; | |
| } | |
| void setDropped() { | |
| this.status = Status.DROPPED; | |
| } | |
| void setOverwritten() { | |
| this.status = Status.OVERWRITTEN; | |
| } | |
| Status status() { | |
| return status; | |
| } | |
| String className() { | |
| return outer.className(); | |
| } | |
| String classFullName() { | |
| return outer.classFullName(); | |
| } | |
| /** | |
| * Top-level wrap | |
| * @return | |
| */ | |
| OuterWrap outerWrap() { | |
| return outer; | |
| } | |
| /** | |
| * Basically, class version for this Key. | |
| * @return int | |
| */ | |
| int sequenceNumber() { | |
| return seq; | |
| } | |
| Wrap guts() { | |
| return guts; | |
| } | |
| boolean isExecutable() { | |
| return subkind.isExecutable(); | |
| } | |
| } |