Snippet.java revision 3695:40468274ff3b
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 java.util.Collection;
29import java.util.Collections;
30import java.util.List;
31
32/**
33 * A Snippet represents a snippet of Java source code as passed to
34 * {@link jdk.jshell.JShell#eval}.  It is associated only with the
35 * {@link jdk.jshell.JShell JShell} instance that created it.
36 * An instance of Snippet (including its subclasses) is immutable: an access to
37 * any of its methods will always return the same result.
38 * For information about the current state of the snippet within the JShell
39 * state engine, query {@code JShell} passing the Snippet.
40 * <p>
41 * Because it is immutable, {@code Snippet} (and subclasses) is thread-safe.
42 * @author Robert Field
43 * @see jdk.jshell.JShell#status
44 */
45public abstract class Snippet {
46
47    /**
48     * Describes the general kind of snippet.
49     * The {@code Kind} is an immutable property of a Snippet.
50     * It is accessed with {@link jdk.jshell.Snippet#kind()}.
51     * The {@code Kind} can be used to determine which
52     * subclass of Snippet it is. For example,
53     * {@link jdk.jshell.JShell#eval eval("int three() { return 3; }")} will
54     * return a snippet creation event.  The {@code Kind} of that Snippet
55     * will be {@code METHOD}, from which you know that the subclass
56     * of {@code Snippet} is {@code MethodSnippet} and it can be
57     * cast as such.
58     */
59    public enum Kind {
60        /**
61         * An import declaration: {@code import} ...
62         * The snippet is an instance of {@link jdk.jshell.ImportSnippet}.
63         * <P>
64         * An import can be a single type import
65         * ({@link jdk.jshell.Snippet.SubKind#SINGLE_TYPE_IMPORT_SUBKIND}),
66         * a static single import
67         * ({@link jdk.jshell.Snippet.SubKind#SINGLE_STATIC_IMPORT_SUBKIND}),
68         * an on-demand type import
69         * ({@link jdk.jshell.Snippet.SubKind#TYPE_IMPORT_ON_DEMAND_SUBKIND}),
70         * or a static on-demand type import
71         * ({@link jdk.jshell.Snippet.SubKind#SINGLE_STATIC_IMPORT_SUBKIND}) --
72         * use {@link jdk.jshell.Snippet#subKind()} to distinguish.
73         * <P>
74         * @jls 8.3: importDeclaration.
75         * <P>
76         * An import declaration is {@linkplain Kind#isPersistent() persistent}.
77         */
78        IMPORT(true),
79
80        /**
81         * A type declaration.
82         * Which includes: NormalClassDeclaration, EnumDeclaration,
83         * NormalInterfaceDeclaration, and AnnotationTypeDeclaration.
84         * The snippet is an instance of {@link jdk.jshell.TypeDeclSnippet}.
85         * <P>
86         * A type declaration may be an interface
87         * {@link jdk.jshell.Snippet.SubKind#INTERFACE_SUBKIND},
88         * classes {@link jdk.jshell.Snippet.SubKind#CLASS_SUBKIND}, enums, and
89         * annotation interfaces -- see {@link jdk.jshell.Snippet.SubKind} to
90         * differentiate.
91         * <P>
92         * @jls 7.6: TypeDeclaration.
93         * <P>
94         * A type declaration is {@linkplain Kind#isPersistent() persistent}.
95         */
96        TYPE_DECL(true),
97
98        /**
99         * A method declaration.
100         * The snippet is an instance of {@link jdk.jshell.MethodSnippet}.
101         * <P>
102         * @jls 8.4: MethodDeclaration.
103         * <P>
104         * A method declaration is {@linkplain Kind#isPersistent() persistent}.
105         */
106        METHOD(true),
107
108        /**
109         * One variable declaration.
110         * Corresponding to one <i>VariableDeclarator</i>.
111         * The snippet is an instance of {@link jdk.jshell.VarSnippet}.
112         * <P>
113         * The variable may be with or without initializer, or be a temporary
114         * variable representing an expression -- see
115         * {@link jdk.jshell.Snippet.SubKind}to differentiate.
116         * <P>
117         * @jls 8.3: FieldDeclaration.
118         * <P>
119         * A variable declaration is {@linkplain Kind#isPersistent() persistent}.
120         */
121        VAR(true),
122
123        /**
124         * An expression, with or without side-effects.
125         * The snippet is an instance of {@link jdk.jshell.ExpressionSnippet}.
126         * <P>
127         * The expression is currently either a simple named reference to a
128         * variable ({@link jdk.jshell.Snippet.SubKind#VAR_VALUE_SUBKIND}) or an
129         * assignment (both of which have natural referencing
130         * names) -- see {@link jdk.jshell.Snippet.SubKind} to differentiate.
131         * All other expression forms (operators, method calls, ...) generate a
132         * scratch variable and so are instead of the VAR Kind.
133         * <P>
134         * @jls 15: Expression.
135         */
136        EXPRESSION(false),
137
138        /**
139         * A statement.
140         * The snippet is an instance of {@link jdk.jshell.StatementSnippet}.
141         * <P>
142         * @jls 14.5: Statement.
143         */
144        STATEMENT(false),
145
146        /**
147         * A syntactically incorrect input for which the specific
148         * kind could not be determined.
149         * The snippet is an instance of {@link jdk.jshell.ErroneousSnippet}.
150         */
151        ERRONEOUS(false);
152
153        private final boolean isPersistent;
154
155        Kind(boolean isPersistent) {
156            this.isPersistent = isPersistent;
157        }
158
159        /**
160         * Indicates whether this {@code Kind} of Snippet is persistent. Only
161         * declarations are persistent because they influence future Snippets.
162         * <p>
163         * Note that though the {@code Kind} of
164         * a Snippet may be persistent, that does not mean that the Snippet will
165         * persist; For example it may be invalid or have been dropped.  See:
166         * {@link jdk.jshell.Snippet.Status#isDefined()}.
167         *
168         * @return {@code true} if this {@code Kind} of {@code Snippet} is
169         * visible to subsequent evaluations; otherwise {@code false}
170         */
171        public boolean isPersistent() {
172            return isPersistent;
173        }
174    }
175
176    /**
177     * The detailed variety of a snippet.  This is a sub-classification of the
178     * Kind.  The Kind of a SubKind is accessible with
179     * {@link jdk.jshell.Snippet.SubKind#kind}.
180     */
181    public enum SubKind {
182
183        /**
184         * Single-Type-Import Declaration.
185         * An import declaration of a single type.
186         * @jls 7.5.1 SingleTypeImportDeclaration.
187         */
188        SINGLE_TYPE_IMPORT_SUBKIND(Kind.IMPORT),
189
190        /**
191         * Type-Import-on-Demand Declaration.
192         * A non-static "star" import.
193         * @jls 7.5.2. TypeImportOnDemandDeclaration.
194         */
195        TYPE_IMPORT_ON_DEMAND_SUBKIND(Kind.IMPORT),
196
197        /**
198         * Single-Static-Import Declaration.
199         * An import of a static member.
200         * @jls 7.5.3 Single-Static-Import.
201         */
202        SINGLE_STATIC_IMPORT_SUBKIND(Kind.IMPORT),
203
204        /**
205         * Static-Import-on-Demand Declaration.
206         * A static "star" import of all static members of a named type.
207         * @jls 7.5.4. Static-Import-on-Demand Static "star" import.
208         */
209        STATIC_IMPORT_ON_DEMAND_SUBKIND(Kind.IMPORT),
210
211        /**
212         * A class declaration.
213         * A {@code SubKind} of {@link Kind#TYPE_DECL}.
214         * @jls 8.1. NormalClassDeclaration.
215         */
216        CLASS_SUBKIND(Kind.TYPE_DECL),
217
218        /**
219         * An interface declaration.
220         * A {@code SubKind} of {@link Kind#TYPE_DECL}.
221         * @jls 9.1. NormalInterfaceDeclaration.
222         */
223        INTERFACE_SUBKIND(Kind.TYPE_DECL),
224
225        /**
226         * An enum declaration.
227         * A {@code SubKind} of {@link Kind#TYPE_DECL}.
228         * @jls 8.9. EnumDeclaration.
229         */
230        ENUM_SUBKIND(Kind.TYPE_DECL),
231
232        /**
233         * An annotation interface declaration. A {@code SubKind} of
234         * {@link Kind#TYPE_DECL}.
235         * @jls 9.6. AnnotationTypeDeclaration.
236         */
237        ANNOTATION_TYPE_SUBKIND(Kind.TYPE_DECL),
238
239        /**
240         * A method. The only {@code SubKind} for {@link Kind#METHOD}.
241         * @jls 8.4. MethodDeclaration.
242         */
243        METHOD_SUBKIND(Kind.METHOD),
244
245        /**
246         * A variable declaration without initializer.
247         * A {@code SubKind} of {@link Kind#VAR}.
248         * @jls 8.3. VariableDeclarator without VariableInitializer in
249         * FieldDeclaration.
250         */
251        VAR_DECLARATION_SUBKIND(Kind.VAR),
252
253        /**
254         * A variable declaration with an initializer expression. A
255         * {@code SubKind} of {@link Kind#VAR}.
256         * @jls 8.3. VariableDeclarator with VariableInitializer in
257         * FieldDeclaration.
258         */
259        VAR_DECLARATION_WITH_INITIALIZER_SUBKIND(Kind.VAR, true, true),
260
261        /**
262         * An expression whose value has been stored in a temporary variable. A
263         * {@code SubKind} of {@link Kind#VAR}.
264         * @jls 15. Primary.
265         */
266        TEMP_VAR_EXPRESSION_SUBKIND(Kind.VAR, true, true),
267
268        /**
269         * A simple variable reference expression. A {@code SubKind} of
270         * {@link Kind#EXPRESSION}.
271         * @jls 15.11. Field Access as 3.8. Identifier.
272         */
273        VAR_VALUE_SUBKIND(Kind.EXPRESSION, true, true),
274
275        /**
276         * An assignment expression. A {@code SubKind} of
277         * {@link Kind#EXPRESSION}.
278         * @jls 15.26. Assignment.
279         */
280        ASSIGNMENT_SUBKIND(Kind.EXPRESSION, true, true),
281
282        /**
283         * An expression which has not been wrapped in a temporary variable
284         * (reserved). A {@code SubKind} of {@link Kind#EXPRESSION}.
285         */
286        OTHER_EXPRESSION_SUBKIND(Kind.EXPRESSION, true, true),
287
288        /**
289         * A statement. The only {@code SubKind} for {@link Kind#STATEMENT}.
290         * @jls 14.5. Statement.
291         */
292        STATEMENT_SUBKIND(Kind.STATEMENT, true, false),
293
294        /**
295         * An unknown snippet. The only {@code SubKind} for
296         * {@link Kind#ERRONEOUS}.
297         */
298        UNKNOWN_SUBKIND(Kind.ERRONEOUS, false, false);
299
300        private final boolean isExecutable;
301        private final boolean hasValue;
302        private final Kind kind;
303
304        SubKind(Kind kind) {
305            this.kind = kind;
306            this.isExecutable = false;
307            this.hasValue = false;
308        }
309
310        SubKind(Kind kind, boolean isExecutable, boolean hasValue) {
311            this.kind = kind;
312            this.isExecutable = isExecutable;
313            this.hasValue = hasValue;
314        }
315
316        /**
317         * Indicates whether this {@code SubKind} is executable.
318         *
319         * @return {@code true} if this {@code SubKind} can
320         * be executed; otherwise {@code false}
321         */
322        public boolean isExecutable() {
323            return isExecutable;
324        }
325
326        /**
327         * Indicates whether this {@code SubKind} is executable and
328         * is non-{@code void}.
329         *
330         * @return {@code true} if this {@code SubKind} has
331         * a value; otherwise {@code false}
332         */
333        public boolean hasValue() {
334            return hasValue;
335        }
336
337        /**
338         * The {@link Snippet.Kind} that corresponds to this {@code SubKind}.
339         *
340         * @return the fixed {@code Kind} for this {@code SubKind}
341         */
342        public Kind kind() {
343            return kind;
344        }
345    }
346
347    /**
348     * Describes the current state of a Snippet.
349     * This is a dynamic property of a Snippet within the JShell state --
350     * thus is retrieved with a {@linkplain
351     * jdk.jshell.JShell#status(jdk.jshell.Snippet) query on {@code JShell}}.
352     * <p>
353     * The {@code Status} changes as the state changes.
354     * For example, creation of another snippet with
355     * {@link jdk.jshell.JShell#eval(java.lang.String) eval}
356     * may resolve dependencies of this Snippet (or invalidate those dependencies), or
357     * {@linkplain jdk.jshell.Snippet.Status#OVERWRITTEN overwrite}
358     * this Snippet changing its
359     * {@code Status}.
360     * <p>
361     * Important properties associated with {@code Status} are:
362     * {@link jdk.jshell.Snippet.Status#isDefined()}, if it is visible to other
363     * existing and new snippets; and
364     * {@link jdk.jshell.Snippet.Status#isActive()}, if, as the
365     * JShell state changes, the snippet will update, possibly
366     * changing {@code Status}.
367     * An executable Snippet can only be executed if it is in the the
368     * {@link jdk.jshell.Snippet.Status#VALID} {@code Status}.
369     * @see JShell#status(jdk.jshell.Snippet)
370     */
371    public enum Status {
372        /**
373         * The snippet is a valid snippet
374         * (in the context of current {@code JShell} state).
375         * Only snippets with {@code VALID}
376         * {@code Status} can be executed (though not all
377         * {@code VALID} snippets have executable code).
378         * <p>
379         * The snippet is defined
380         * ({@link Status#isDefined() isDefined() == true}).
381         * If the snippet is a declaration or import
382         * ({@link Snippet.Kind#isPersistent()}),
383         * it is visible to other snippets
384         * <p>
385         * The snippet will update as dependents change
386         * ({@link Status#isActive() isActive() == true}), its
387         * status could become {@code RECOVERABLE_DEFINED}, {@code RECOVERABLE_NOT_DEFINED},
388         * {@code DROPPED}, or {@code OVERWRITTEN}.
389         */
390        VALID(true, true),
391
392        /**
393         * The snippet is a declaration snippet with potentially recoverable
394         * unresolved references or other issues in its body
395         * (in the context of current {@code JShell} state).
396         * Only a {@link jdk.jshell.DeclarationSnippet} can have this
397         * {@code Status}.
398         * <p>
399         * The snippet has a valid signature and it is visible to other
400         * snippets
401         * ({@link Status#isDefined() isDefined() == true})
402         * and thus can be referenced in existing or new snippets
403         * but the snippet cannot be executed.
404         * An {@link UnresolvedReferenceException} will be thrown on an attempt
405         * to execute it.
406         * <p>
407         * The snippet will update as dependents change
408         * ({@link Status#isActive() isActive() == true}), its
409         * status could become {@code VALID}, {@code RECOVERABLE_NOT_DEFINED},
410         * {@code DROPPED}, or {@code OVERWRITTEN}.
411         * <p>
412         * Note: both {@code RECOVERABLE_DEFINED} and {@code RECOVERABLE_NOT_DEFINED}
413         * indicate potentially recoverable errors, they differ in that, for
414         * {@code RECOVERABLE_DEFINED}, the snippet is
415         * {@linkplain Status#isDefined() defined}.
416         */
417        RECOVERABLE_DEFINED(true, true),
418
419        /**
420         * The snippet is a declaration snippet with potentially recoverable
421         * unresolved references or other issues
422         * (in the context of current {@code JShell} state).
423         * Only a {@link jdk.jshell.DeclarationSnippet} can have this
424         * {@code Status}.
425         * <p>
426         * The snippet has an invalid signature or the implementation is
427         * otherwise unable to define it.
428         * The snippet it is not visible to other snippets
429         * ({@link Status#isDefined() isDefined() == false})
430         * and thus cannot be referenced or executed.
431         * <p>
432         * The snippet will update as dependents change
433         * ({@link Status#isActive() isActive() == true}), its
434         * status could become {@code VALID}, {@code RECOVERABLE_DEFINED},
435         * {@code DROPPED}, or {@code OVERWRITTEN}.
436         * <p>
437         * Note: both {@code RECOVERABLE_DEFINED} and {@code RECOVERABLE_NOT_DEFINED}
438         * indicate potentially recoverable errors, they differ in that, for
439         * {@code RECOVERABLE_DEFINED}, the snippet is
440         * {@linkplain Status#isDefined() defined}.
441         */
442        RECOVERABLE_NOT_DEFINED(true, false),
443
444        /**
445         * The snippet is inactive because of an explicit call to
446         * the {@link JShell#drop(Snippet)}.
447         * <p>
448         * The snippet is not visible to other snippets
449         * ({@link Status#isDefined() isDefined() == false})
450         * and thus cannot be referenced or executed.
451         * <p>
452         * The snippet will not update as dependents change
453         * ({@link Status#isActive() isActive() == false}), its
454         * {@code Status} will never change again.
455         */
456        DROPPED(false, false),
457
458        /**
459         * The snippet is inactive because it has been replaced by a new
460         * snippet.  This occurs when the new snippet added with
461         * {@link jdk.jshell.JShell#eval} matches a previous snippet.
462         * A {@code TypeDeclSnippet} will match another
463         * {@code TypeDeclSnippet} if the names match.
464         * For example {@code class X { }} will overwrite
465         * {@code class X { int ii; }} or
466         * {@code interface X { }}.
467         * A {@code MethodSnippet} will match another
468         * {@code MethodSnippet} if the names and parameter types
469         * match.
470         * For example {@code void m(int a) { }} will overwrite
471         * {@code int m(int a) { return a+a; }}.
472         * A {@code VarSnippet} will match another
473         * {@code VarSnippet} if the names match.
474         * For example {@code double z;} will overwrite
475         * {@code long z = 2L;}.
476         * Only a {@link jdk.jshell.PersistentSnippet} can have this
477         * {@code Status}.
478         * <p>
479         * The snippet is not visible to other snippets
480         * ({@link Status#isDefined() isDefined() == false})
481         * and thus cannot be referenced or executed.
482         * <p>
483         * The snippet will not update as dependents change
484         * ({@link Status#isActive() isActive() == false}), its
485         * {@code Status} will never change again.
486         */
487        OVERWRITTEN(false, false),
488
489        /**
490         * The snippet is inactive because it failed compilation on initial
491         * evaluation and it is not capable of becoming valid with further
492         * changes to the JShell state.
493         * <p>
494         * The snippet is not visible to other snippets
495         * ({@link Status#isDefined() isDefined() == false})
496         * and thus cannot be referenced or executed.
497         * <p>
498         * The snippet will not update as dependents change
499         * ({@link Status#isActive() isActive() == false}), its
500         * {@code Status} will never change again.
501         */
502        REJECTED(false, false),
503
504        /**
505         * The snippet is inactive because it does not yet exist.
506         * Used only in {@link SnippetEvent#previousStatus} for new
507         * snippets.
508         * {@link jdk.jshell.JShell#status(jdk.jshell.Snippet) JShell.status(Snippet)}
509         * will never return this {@code Status}.
510         * <p>
511         * Vacuously, {@link Status#isDefined() isDefined()} and
512         * {@link Status#isActive() isActive()} are both defined {@code false}.
513         */
514        NONEXISTENT(false, false);
515
516        private final boolean isActive;
517        private final boolean isDefined;
518
519        Status(boolean isActive, boolean isDefined) {
520            this.isActive = isActive;
521            this.isDefined = isDefined;
522        }
523
524        /**
525         * Indicates whether the Snippet is active, that is,
526         * will a {@linkplain jdk.jshell.PersistentSnippet persistent}
527         * snippet be re-evaluated when a new
528         * {@link JShell#eval(java.lang.String) JShell.eval(String)} or
529         * {@link JShell#drop(jdk.jshell.Snippet)
530         * JShell.drop(Snippet)} that could change
531         * its status is invoked.  This is more broad than
532         * {@link Status#isDefined()} since a Snippet which is
533         * {@link Status#RECOVERABLE_NOT_DEFINED}
534         * will be updated.
535         *
536         * @return {@code true} if the Snippet is active; otherwise {@code false}
537         */
538        public boolean isActive() {
539            return isActive;
540        }
541
542        /**
543         * Indicates whether the snippet is currently part of the defined state
544         * of the JShell. Is it visible to compilation of other snippets?
545         * @return {@code true} if the Snippet is defined; otherwise
546         * {@code false}
547         */
548        public boolean isDefined() {
549            return isDefined;
550        }
551    }
552
553    private final Key key;
554    private final String source;
555    private final Wrap guts;
556    final String unitName;
557    private final SubKind subkind;
558
559    private int seq;
560    private String id;
561    private OuterWrap outer;
562    private Status status;
563    private List<String> unresolved;
564    private DiagList diagnostics;
565    private final DiagList syntheticDiags;
566
567    Snippet(Key key, String userSource, Wrap guts, String unitName,
568            SubKind subkind, DiagList syntheticDiags) {
569        this.key = key;
570        this.source = userSource;
571        this.guts = guts;
572        this.unitName = unitName;
573        this.subkind = subkind;
574        this.syntheticDiags = syntheticDiags==null
575                ? new DiagList()
576                : syntheticDiags;
577        this.status = Status.NONEXISTENT;
578        setSequenceNumber(0);
579    }
580
581    /**** public access ****/
582
583    /**
584     * The unique identifier for the snippet. No two active snippets will have
585     * the same id().  Value of id has no prescribed meaning.  The details of
586     * how the id is generated and the mechanism to change it is documented in
587     * {@link JShell.Builder#idGenerator(BiFunction)}.
588     * @return the snippet id string.
589     */
590    public String id() {
591        return id;
592    }
593
594    /**
595     * The {@link jdk.jshell.Snippet.Kind} for the snippet.
596     * Indicates the subclass of Snippet.
597     * @return the Kind of the snippet
598     * @see Snippet.Kind
599     */
600    public Kind kind() {
601        return subkind.kind();
602    }
603
604    /**
605     * Return the {@link SubKind} of snippet.
606     * The SubKind is useful for feedback to users.
607     * @return the SubKind corresponding to this snippet
608     */
609    public SubKind subKind() {
610        return subkind;
611    }
612
613    /**
614     * Return the source code of the snippet.
615     * @return the source code corresponding to this snippet
616     */
617    public String source() {
618        return source;
619    }
620
621    @Override
622    public String toString() {
623        StringBuilder sb = new StringBuilder();
624        sb.append("Snippet:");
625        if (key() != null) {
626            sb.append(key().toString());
627        }
628        sb.append('-');
629        sb.append(source);
630        return sb.toString();
631    }
632
633    //**** internal access ****
634
635    String name() {
636        return unitName;
637    }
638
639    Key key() {
640        return key;
641    }
642
643    List<String> unresolved() {
644        return Collections.unmodifiableList(unresolved);
645    }
646
647    DiagList diagnostics() {
648        return diagnostics;
649    }
650
651    DiagList syntheticDiags() {
652        return syntheticDiags;
653    }
654
655    /**
656     * @return the corralled guts
657     */
658    Wrap corralled() {
659        return null;
660    }
661
662    Collection<String> declareReferences() {
663        return null;
664    }
665
666    Collection<String> bodyReferences() {
667        return null;
668    }
669
670    String importLine(JShell state) {
671        return "";
672    }
673
674    void setId(String id) {
675        this.id = id;
676    }
677
678    final void setSequenceNumber(int seq) {
679        this.seq = seq;
680    }
681
682    void setOuterWrap(OuterWrap outer) {
683        this.outer = outer;
684    }
685
686    void setCompilationStatus(Status status, List<String> unresolved, DiagList diagnostics) {
687        this.status = status;
688        this.unresolved = unresolved;
689        this.diagnostics = diagnostics;
690    }
691
692    void setDiagnostics(DiagList diagnostics) {
693        this.diagnostics = diagnostics;
694    }
695
696    void setFailed(DiagList diagnostics) {
697        this.seq = -1;
698        this.outer = null;
699        this.status = Status.REJECTED;
700        this.unresolved = Collections.emptyList();
701        this.diagnostics = diagnostics;
702    }
703
704    void setDropped() {
705        this.status = Status.DROPPED;
706    }
707
708    void setOverwritten() {
709        this.status = Status.OVERWRITTEN;
710    }
711
712    Status status() {
713        return status;
714    }
715
716    String className() {
717        return outer.className();
718    }
719
720    String classFullName() {
721        return outer.classFullName();
722    }
723
724    /**
725     * Top-level wrap
726     * @return
727     */
728    OuterWrap outerWrap() {
729        return outer;
730    }
731
732    /**
733     * Basically, class version for this Key.
734     * @return int
735     */
736    int sequenceNumber() {
737        return seq;
738    }
739
740    Wrap guts() {
741        return guts;
742    }
743
744    boolean isExecutable() {
745        return subkind.isExecutable();
746    }
747
748}
749