SourceCodeAnalysis.java revision 3062:15bdc18525ff
1/*
2 * Copyright (c) 2014, 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.List;
29
30/**
31 * Provides analysis utilities for source code input.
32 * Optional functionality that provides for a richer interactive experience.
33 * Includes completion analysis:
34 * Is the input a complete snippet of code?
35 * Do I need to prompt for more input?
36 * Would adding a semicolon make it complete?
37 * Is there more than one snippet?
38 * etc.
39 * Also includes completion suggestions, as might be used in tab-completion.
40 *
41 */
42public abstract class SourceCodeAnalysis {
43
44    /**
45     * Given an input string, find the first snippet of code (one statement,
46     * definition, import, or expression) and evaluate if it is complete.
47     * @param input the input source string
48     * @return a CompletionInfo instance with location and completeness info
49     */
50    public abstract CompletionInfo analyzeCompletion(String input);
51
52    /**
53     * Compute possible follow-ups for the given input.
54     * Uses information from the current <code>JShell</code> state, including
55     * type information, to filter the suggestions.
56     * @param input the user input, so far
57     * @param cursor the current position of the cursors in the given {@code input} text
58     * @param anchor outgoing parameter - when an option will be completed, the text between
59     *               the anchor and cursor will be deleted and replaced with the given option
60     * @return list of candidate continuations of the given input.
61     */
62    public abstract List<Suggestion> completionSuggestions(String input, int cursor, int[] anchor);
63
64    /**
65     * Compute a description/help string for the given user's input.
66     * @param input the snippet the user wrote so far
67     * @param cursor the current position of the cursors in the given {@code input} text
68     * @return description/help string for the given user's input
69     */
70    public abstract String documentation(String input, int cursor);
71
72    /**
73     * Internal only constructor
74     */
75    SourceCodeAnalysis() {}
76
77    /**
78     * The result of <code>analyzeCompletion(String input)</code>.
79     * Describes the completeness and position of the first snippet in the given input.
80     */
81    public static class CompletionInfo {
82
83        public CompletionInfo(Completeness completeness, int unitEndPos, String source, String remaining) {
84            this.completeness = completeness;
85            this.unitEndPos = unitEndPos;
86            this.source = source;
87            this.remaining = remaining;
88        }
89
90        /**
91         * The analyzed completeness of the input.
92         */
93        public final Completeness completeness;
94
95        /**
96         * The end of the first unit of source.
97         */
98        public final int unitEndPos;
99
100        /**
101         * Source code for the first unit of code input.  For example, first
102         * statement, or first method declaration.  Trailing semicolons will
103         * be added, as needed
104         */
105        public final String source;
106
107        /**
108         * Input remaining after the source
109         */
110        public final String remaining;
111    }
112
113    /**
114     * Describes the completeness of the given input.
115     */
116    public enum Completeness {
117        /**
118         * The input is a complete source snippet (declaration or statement) as is.
119         */
120        COMPLETE(true),
121
122        /**
123         * With this addition of a semicolon the input is a complete source snippet.
124         * This will only be returned when the end of input is encountered.
125         */
126        COMPLETE_WITH_SEMI(true),
127
128        /**
129         * There must be further source beyond the given input in order for it
130         * to be complete.  A semicolon would not complete it.
131         * This will only be returned when the end of input is encountered.
132         */
133        DEFINITELY_INCOMPLETE(false),
134
135        /**
136         * A statement with a trailing (non-terminated) empty statement.
137         * Though technically it would be a complete statement
138         * with the addition of a semicolon, it is rare
139         * that that assumption is the desired behavior.
140         * The input is considered incomplete.  Comments and white-space are
141         * still considered empty.
142         */
143        CONSIDERED_INCOMPLETE(false),
144
145
146        /**
147         * An empty input.
148         * The input is considered incomplete.  Comments and white-space are
149         * still considered empty.
150         */
151        EMPTY(false),
152
153        /**
154         * The completeness of the input could not be determined because it
155         * contains errors. Error detection is not a goal of completeness
156         * analysis, however errors interfered with determining its completeness.
157         * The input is considered complete because evaluating is the best
158         * mechanism to get error information.
159         */
160        UNKNOWN(true);
161
162        /**
163         * Is the first snippet of source complete. For example, "x=" is not
164         * complete, but "x=2" is complete, even though a subsequent line could
165         * make it "x=2+2". Already erroneous code is marked complete.
166         */
167        public final boolean isComplete;
168
169        Completeness(boolean isComplete) {
170            this.isComplete = isComplete;
171        }
172    }
173
174    /**
175     * A candidate for continuation of the given user's input.
176     */
177    public static class Suggestion {
178
179        /**
180         * Create a {@code Suggestion} instance.
181         * @param continuation a candidate continuation of the user's input
182         * @param isSmart is the candidate "smart"
183         */
184        public Suggestion(String continuation, boolean isSmart) {
185            this.continuation = continuation;
186            this.isSmart = isSmart;
187        }
188
189        /**
190         * The candidate continuation of the given user's input.
191         */
192        public final String continuation;
193
194        /**
195         * Is it an input continuation that matches the target type and is thus more
196         * likely to be the desired continuation. A smart continuation
197         * is preferred.
198         */
199        public final boolean isSmart;
200    }
201}
202