duke@1: /* jjg@1521: * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@1: * duke@1: * This code is free software; you can redistribute it and/or modify it duke@1: * under the terms of the GNU General Public License version 2 only, as ohair@554: * published by the Free Software Foundation. Oracle designates this duke@1: * particular file as subject to the "Classpath" exception as provided ohair@554: * by Oracle in the LICENSE file that accompanied this code. duke@1: * duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@1: * version 2 for more details (a copy is included in the LICENSE file that duke@1: * accompanied this code). duke@1: * duke@1: * You should have received a copy of the GNU General Public License version duke@1: * 2 along with this work; if not, write to the Free Software Foundation, duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@1: * ohair@554: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@554: * or visit www.oracle.com if you need additional information or have any ohair@554: * questions. duke@1: */ duke@1: duke@1: package javax.lang.model; duke@1: duke@1: import java.util.Collections; duke@1: import java.util.Set; duke@1: import java.util.HashSet; duke@1: duke@1: /** duke@1: * Source versions of the Java™ programming language. duke@1: * jjh@972: * See the appropriate edition of jjh@972: * The Java™ Language Specification jjh@972: * for information about a particular source version. duke@1: * duke@1: *

Note that additional source version constants will be added to duke@1: * model future releases of the language. duke@1: * duke@1: * @author Joseph D. Darcy duke@1: * @author Scott Seligman duke@1: * @author Peter von der Ahé duke@1: * @since 1.6 duke@1: */ duke@1: public enum SourceVersion { duke@1: /* jjg@1521: * Summary of language evolution duke@1: * 1.1: nested classes duke@1: * 1.2: strictfp duke@1: * 1.3: no changes duke@1: * 1.4: assert duke@1: * 1.5: annotations, generics, autoboxing, var-args... duke@1: * 1.6: no changes darcy@1867: * 1.7: diamond syntax, try-with-resources, etc. darcy@1867: * 1.8: lambda expressions and default methods duke@1: */ duke@1: duke@1: /** duke@1: * The original version. duke@1: * jjh@972: * The language described in jjh@972: * The Java™ Language Specification, First Edition. duke@1: */ duke@1: RELEASE_0, duke@1: duke@1: /** duke@1: * The version recognized by the Java Platform 1.1. duke@1: * jjh@972: * The language is {@code RELEASE_0} augmented with nested classes as described in the 1.1 update to jjh@972: * The Java™ Language Specification, First Edition. duke@1: */ duke@1: RELEASE_1, duke@1: duke@1: /** duke@1: * The version recognized by the Java 2 Platform, Standard Edition, duke@1: * v 1.2. duke@1: * jjh@972: * The language described in jjh@972: * The Java™ Language Specification, jjh@972: * Second Edition, which includes the {@code duke@1: * strictfp} modifier. duke@1: */ duke@1: RELEASE_2, duke@1: duke@1: /** duke@1: * The version recognized by the Java 2 Platform, Standard Edition, duke@1: * v 1.3. duke@1: * duke@1: * No major changes from {@code RELEASE_2}. duke@1: */ duke@1: RELEASE_3, duke@1: duke@1: /** duke@1: * The version recognized by the Java 2 Platform, Standard Edition, duke@1: * v 1.4. duke@1: * duke@1: * Added a simple assertion facility. duke@1: */ duke@1: RELEASE_4, duke@1: duke@1: /** duke@1: * The version recognized by the Java 2 Platform, Standard duke@1: * Edition 5.0. duke@1: * jjh@972: * The language described in jjh@972: * The Java™ Language Specification, jjh@972: * Third Edition. First release to support duke@1: * generics, annotations, autoboxing, var-args, enhanced {@code duke@1: * for} loop, and hexadecimal floating-point literals. duke@1: */ duke@1: RELEASE_5, duke@1: duke@1: /** duke@1: * The version recognized by the Java Platform, Standard Edition duke@1: * 6. duke@1: * duke@1: * No major changes from {@code RELEASE_5}. duke@1: */ duke@1: RELEASE_6, duke@1: duke@1: /** duke@1: * The version recognized by the Java Platform, Standard Edition duke@1: * 7. duke@1: * darcy@1867: * Additions in this release include, diamond syntax for darcy@1867: * constructors, {@code try}-with-resources, strings in switch, darcy@1867: * binary literals, and multi-catch. duke@1: * @since 1.7 duke@1: */ darcy@1042: RELEASE_7, darcy@1042: darcy@1042: /** darcy@1042: * The version recognized by the Java Platform, Standard Edition darcy@1042: * 8. darcy@1042: * darcy@1867: * Additions in this release include lambda expressions and default methods. darcy@1042: * @since 1.8 darcy@1042: */ darcy@1042: RELEASE_8; duke@1: duke@1: // Note that when adding constants for newer releases, the duke@1: // behavior of latest() and latestSupported() must be updated too. duke@1: duke@1: /** duke@1: * Returns the latest source version that can be modeled. duke@1: * duke@1: * @return the latest source version that can be modeled duke@1: */ duke@1: public static SourceVersion latest() { darcy@1042: return RELEASE_8; duke@1: } duke@1: duke@1: private static final SourceVersion latestSupported = getLatestSupported(); duke@1: duke@1: private static SourceVersion getLatestSupported() { duke@1: try { duke@1: String specVersion = System.getProperty("java.specification.version"); darcy@1042: darcy@1042: if ("1.8".equals(specVersion)) darcy@1042: return RELEASE_8; darcy@1042: else if("1.7".equals(specVersion)) duke@1: return RELEASE_7; darcy@1042: else if("1.6".equals(specVersion)) duke@1: return RELEASE_6; duke@1: } catch (SecurityException se) {} duke@1: duke@1: return RELEASE_5; duke@1: } duke@1: duke@1: /** duke@1: * Returns the latest source version fully supported by the duke@1: * current execution environment. {@code RELEASE_5} or later must duke@1: * be returned. duke@1: * duke@1: * @return the latest source version that is fully supported duke@1: */ duke@1: public static SourceVersion latestSupported() { duke@1: return latestSupported; duke@1: } duke@1: duke@1: /** duke@1: * Returns whether or not {@code name} is a syntactically valid duke@1: * identifier (simple name) or keyword in the latest source duke@1: * version. The method returns {@code true} if the name consists duke@1: * of an initial character for which {@link duke@1: * Character#isJavaIdentifierStart(int)} returns {@code true}, duke@1: * followed only by characters for which {@link duke@1: * Character#isJavaIdentifierPart(int)} returns {@code true}. duke@1: * This pattern matches regular identifiers, keywords, and the duke@1: * literals {@code "true"}, {@code "false"}, and {@code "null"}. duke@1: * The method returns {@code false} for all other strings. duke@1: * duke@1: * @param name the string to check duke@1: * @return {@code true} if this string is a duke@1: * syntactically valid identifier or keyword, {@code false} duke@1: * otherwise. duke@1: */ duke@1: public static boolean isIdentifier(CharSequence name) { duke@1: String id = name.toString(); duke@1: duke@1: if (id.length() == 0) { duke@1: return false; duke@1: } duke@1: int cp = id.codePointAt(0); duke@1: if (!Character.isJavaIdentifierStart(cp)) { duke@1: return false; duke@1: } duke@1: for (int i = Character.charCount(cp); duke@1: i < id.length(); duke@1: i += Character.charCount(cp)) { duke@1: cp = id.codePointAt(i); duke@1: if (!Character.isJavaIdentifierPart(cp)) { duke@1: return false; duke@1: } duke@1: } duke@1: return true; duke@1: } duke@1: duke@1: /** duke@1: * Returns whether or not {@code name} is a syntactically valid duke@1: * qualified name in the latest source version. Unlike {@link duke@1: * #isIdentifier isIdentifier}, this method returns {@code false} duke@1: * for keywords and literals. duke@1: * duke@1: * @param name the string to check duke@1: * @return {@code true} if this string is a duke@1: * syntactically valid name, {@code false} otherwise. jjh@972: * @jls 6.2 Names and Identifiers duke@1: */ duke@1: public static boolean isName(CharSequence name) { duke@1: String id = name.toString(); duke@1: duke@1: for(String s : id.split("\\.", -1)) { duke@1: if (!isIdentifier(s) || isKeyword(s)) duke@1: return false; duke@1: } duke@1: return true; duke@1: } duke@1: duke@1: private final static Set keywords; duke@1: static { duke@1: Set s = new HashSet(); duke@1: String [] kws = { duke@1: "abstract", "continue", "for", "new", "switch", duke@1: "assert", "default", "if", "package", "synchronized", duke@1: "boolean", "do", "goto", "private", "this", duke@1: "break", "double", "implements", "protected", "throw", duke@1: "byte", "else", "import", "public", "throws", duke@1: "case", "enum", "instanceof", "return", "transient", duke@1: "catch", "extends", "int", "short", "try", duke@1: "char", "final", "interface", "static", "void", duke@1: "class", "finally", "long", "strictfp", "volatile", duke@1: "const", "float", "native", "super", "while", duke@1: // literals duke@1: "null", "true", "false" duke@1: }; duke@1: for(String kw : kws) duke@1: s.add(kw); duke@1: keywords = Collections.unmodifiableSet(s); duke@1: } duke@1: duke@1: /** duke@1: * Returns whether or not {@code s} is a keyword or literal in the duke@1: * latest source version. duke@1: * duke@1: * @param s the string to check duke@1: * @return {@code true} if {@code s} is a keyword or literal, {@code false} otherwise. duke@1: */ duke@1: public static boolean isKeyword(CharSequence s) { duke@1: String keywordOrLiteral = s.toString(); duke@1: return keywords.contains(keywordOrLiteral); duke@1: } duke@1: }