1 /*
2 * Copyright (c) 2005, 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
38 *
39 * <p>Note that additional source version constants will be added to
40 * model future releases of the language.
41 *
42 * @author Joseph D. Darcy
43 * @author Scott Seligman
44 * @author Peter von der Ahé
45 * @since 1.6
46 */
47 public enum SourceVersion {
48 /*
49 * Summary of language evolution
50 * 1.1: nested classes
51 * 1.2: strictfp
52 * 1.3: no changes
53 * 1.4: assert
54 * 1.5: annotations, generics, autoboxing, var-args...
55 * 1.6: no changes
56 * 1.7: diamond syntax, try-with-resources, etc.
57 * 1.8: lambda expressions and default methods
58 * 9: To be determined
59 */
60
61 /**
62 * The original version.
63 *
64 * The language described in
65 * <cite>The Java™ Language Specification, First Edition</cite>.
66 */
67 RELEASE_0,
68
69 /**
70 * The version recognized by the Java Platform 1.1.
71 *
72 * The language is {@code RELEASE_0} augmented with nested classes as described in the 1.1 update to
73 * <cite>The Java™ Language Specification, First Edition</cite>.
74 */
75 RELEASE_1,
76
77 /**
78 * The version recognized by the Java 2 Platform, Standard Edition,
128 * Additions in this release include, diamond syntax for
129 * constructors, {@code try}-with-resources, strings in switch,
130 * binary literals, and multi-catch.
131 * @since 1.7
132 */
133 RELEASE_7,
134
135 /**
136 * The version recognized by the Java Platform, Standard Edition
137 * 8.
138 *
139 * Additions in this release include lambda expressions and default methods.
140 * @since 1.8
141 */
142 RELEASE_8,
143
144 /**
145 * The version recognized by the Java Platform, Standard Edition
146 * 9.
147 *
148 * @since 9
149 */
150 RELEASE_9;
151
152 // Note that when adding constants for newer releases, the
153 // behavior of latest() and latestSupported() must be updated too.
154
155 /**
156 * Returns the latest source version that can be modeled.
157 *
158 * @return the latest source version that can be modeled
159 */
160 public static SourceVersion latest() {
161 return RELEASE_9;
162 }
163
164 private static final SourceVersion latestSupported = getLatestSupported();
165
166 private static SourceVersion getLatestSupported() {
167 try {
227 cp = id.codePointAt(i);
228 if (!Character.isJavaIdentifierPart(cp)) {
229 return false;
230 }
231 }
232 return true;
233 }
234
235 /**
236 * Returns whether or not {@code name} is a syntactically valid
237 * qualified name in the latest source version. Unlike {@link
238 * #isIdentifier isIdentifier}, this method returns {@code false}
239 * for keywords and literals.
240 *
241 * @param name the string to check
242 * @return {@code true} if this string is a
243 * syntactically valid name, {@code false} otherwise.
244 * @jls 6.2 Names and Identifiers
245 */
246 public static boolean isName(CharSequence name) {
247 String id = name.toString();
248
249 for(String s : id.split("\\.", -1)) {
250 if (!isIdentifier(s) || isKeyword(s))
251 return false;
252 }
253 return true;
254 }
255
256 private final static Set<String> keywords;
257 static {
258 Set<String> s = new HashSet<>();
259 String [] kws = {
260 "abstract", "continue", "for", "new", "switch",
261 "assert", "default", "if", "package", "synchronized",
262 "boolean", "do", "goto", "private", "this",
263 "break", "double", "implements", "protected", "throw",
264 "byte", "else", "import", "public", "throws",
265 "case", "enum", "instanceof", "return", "transient",
266 "catch", "extends", "int", "short", "try",
267 "char", "final", "interface", "static", "void",
268 "class", "finally", "long", "strictfp", "volatile",
269 "const", "float", "native", "super", "while",
270 // literals
271 "null", "true", "false"
272 };
273 for(String kw : kws)
274 s.add(kw);
275 keywords = Collections.unmodifiableSet(s);
276 }
277
278 /**
279 * Returns whether or not {@code s} is a keyword or literal in the
280 * latest source version.
281 *
282 * @param s the string to check
283 * @return {@code true} if {@code s} is a keyword or literal, {@code false} otherwise.
284 */
285 public static boolean isKeyword(CharSequence s) {
286 return keywords.contains(s.toString());
287 }
288 }
|
1 /*
2 * Copyright (c) 2005, 2016, 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
38 *
39 * <p>Note that additional source version constants will be added to
40 * model future releases of the language.
41 *
42 * @author Joseph D. Darcy
43 * @author Scott Seligman
44 * @author Peter von der Ahé
45 * @since 1.6
46 */
47 public enum SourceVersion {
48 /*
49 * Summary of language evolution
50 * 1.1: nested classes
51 * 1.2: strictfp
52 * 1.3: no changes
53 * 1.4: assert
54 * 1.5: annotations, generics, autoboxing, var-args...
55 * 1.6: no changes
56 * 1.7: diamond syntax, try-with-resources, etc.
57 * 1.8: lambda expressions and default methods
58 * 9: modules, small cleanups to 1.7 and 1.8 changes
59 */
60
61 /**
62 * The original version.
63 *
64 * The language described in
65 * <cite>The Java™ Language Specification, First Edition</cite>.
66 */
67 RELEASE_0,
68
69 /**
70 * The version recognized by the Java Platform 1.1.
71 *
72 * The language is {@code RELEASE_0} augmented with nested classes as described in the 1.1 update to
73 * <cite>The Java™ Language Specification, First Edition</cite>.
74 */
75 RELEASE_1,
76
77 /**
78 * The version recognized by the Java 2 Platform, Standard Edition,
128 * Additions in this release include, diamond syntax for
129 * constructors, {@code try}-with-resources, strings in switch,
130 * binary literals, and multi-catch.
131 * @since 1.7
132 */
133 RELEASE_7,
134
135 /**
136 * The version recognized by the Java Platform, Standard Edition
137 * 8.
138 *
139 * Additions in this release include lambda expressions and default methods.
140 * @since 1.8
141 */
142 RELEASE_8,
143
144 /**
145 * The version recognized by the Java Platform, Standard Edition
146 * 9.
147 *
148 * Additions in this release include modules and removal of a
149 * single underscore from the set of legal identifier names.
150 *
151 * @since 9
152 */
153 RELEASE_9;
154
155 // Note that when adding constants for newer releases, the
156 // behavior of latest() and latestSupported() must be updated too.
157
158 /**
159 * Returns the latest source version that can be modeled.
160 *
161 * @return the latest source version that can be modeled
162 */
163 public static SourceVersion latest() {
164 return RELEASE_9;
165 }
166
167 private static final SourceVersion latestSupported = getLatestSupported();
168
169 private static SourceVersion getLatestSupported() {
170 try {
230 cp = id.codePointAt(i);
231 if (!Character.isJavaIdentifierPart(cp)) {
232 return false;
233 }
234 }
235 return true;
236 }
237
238 /**
239 * Returns whether or not {@code name} is a syntactically valid
240 * qualified name in the latest source version. Unlike {@link
241 * #isIdentifier isIdentifier}, this method returns {@code false}
242 * for keywords and literals.
243 *
244 * @param name the string to check
245 * @return {@code true} if this string is a
246 * syntactically valid name, {@code false} otherwise.
247 * @jls 6.2 Names and Identifiers
248 */
249 public static boolean isName(CharSequence name) {
250 return isName(name, latest());
251 }
252
253 /**
254 * Returns whether or not {@code name} is a syntactically valid
255 * qualified name in the given source version. Unlike {@link
256 * #isIdentifier isIdentifier}, this method returns {@code false}
257 * for keywords and literals.
258 *
259 * @param name the string to check
260 * @param version the version to use
261 * @return {@code true} if this string is a
262 * syntactically valid name, {@code false} otherwise.
263 * @jls 6.2 Names and Identifiers
264 * @since 9
265 */
266 public static boolean isName(CharSequence name, SourceVersion version) {
267 String id = name.toString();
268
269 for(String s : id.split("\\.", -1)) {
270 if (!isIdentifier(s) || isKeyword(s, version))
271 return false;
272 }
273 return true;
274 }
275
276 /**
277 * Returns whether or not {@code s} is a keyword or literal in the
278 * latest source version.
279 *
280 * @param s the string to check
281 * @return {@code true} if {@code s} is a keyword or literal, {@code false} otherwise.
282 */
283 public static boolean isKeyword(CharSequence s) {
284 return isKeyword(s, latest());
285 }
286
287 /**
288 * Returns whether or not {@code s} is a keyword or literal in the
289 * given source version.
290 *
291 * @param s the string to check
292 * @param version the version to use
293 * @return {@code true} if {@code s} is a keyword or literal, {@code false} otherwise.
294 * @since 9
295 */
296 public static boolean isKeyword(CharSequence s, SourceVersion version) {
297 String id = s.toString();
298 switch(id) {
299 // A trip through history
300 case "strictfp":
301 return version.compareTo(RELEASE_2) >= 0;
302
303 case "assert":
304 return version.compareTo(RELEASE_4) >= 0;
305
306 case "enum":
307 return version.compareTo(RELEASE_5) >= 0;
308
309 case "_":
310 return version.compareTo(RELEASE_9) >= 0;
311
312 // Keywords common across versions
313 case "abstract": case "continue": case "for": case "new":
314 case "switch": case "default": case "if": case "package":
315 case "synchronized": case "boolean": case "do": case "goto":
316 case "private": case "this": case "break": case "double":
317 case "implements": case "protected": case "throw": case "byte":
318 case "else": case "import": case "public": case "throws":
319 case "case": case "instanceof": case "return": case "transient":
320 case "catch": case "extends": case "int": case "short":
321 case "try": case "char": case "final": case "interface":
322 case "static": case "void": case "class": case "finally":
323 case "long": case "volatile": case "const": case "float":
324 case "native": case "super": case "while":
325 // literals
326 case "null": case "true": case "false":
327 return true;
328
329 default:
330 return false;
331 }
332 }
333 }
|