001 /*
002 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.lang.model;
027
028 import java.util.Collections;
029 import java.util.Set;
030 import java.util.HashSet;
031
032 /**
033 * Source versions of the Java™ programming language.
034 *
035 * See <a
036 * href="http://java.sun.com/docs/books/jls/">http://java.sun.com/docs/books/jls/</a>
037 * for information on editions of <i>The Java™ Language
038 * Specification</i>, including updates and clarifications.
039 *
040 * <p>Note that additional source version constants will be added to
041 * model future releases of the language.
042 *
043 * @author Joseph D. Darcy
044 * @author Scott Seligman
045 * @author Peter von der Ahé
046 * @since 1.6
047 */
048 public enum SourceVersion {
049 /*
050 * Summary of language evoluation
051 * 1.1: nested classes
052 * 1.2: strictfp
053 * 1.3: no changes
054 * 1.4: assert
055 * 1.5: annotations, generics, autoboxing, var-args...
056 * 1.6: no changes
057 */
058
059 /**
060 * The original version.
061 *
062 * The language described in the first edition of <i>The
063 * Java™ Language Specification</i>.
064 */
065 RELEASE_0,
066
067 /**
068 * The version recognized by the Java Platform 1.1.
069 *
070 * The language is {@code RELEASE_0} <a
071 * href="http://java.sun.com/docs/books/jls/first_edition/html/1.1Update.html">augmented</a>
072 * with nested classes.
073 */
074 RELEASE_1,
075
076 /**
077 * The version recognized by the Java 2 Platform, Standard Edition,
078 * v 1.2.
079 *
080 * The language described in <i>The Java™ Language
081 * Specification, Second Edition</i>, which includes the {@code
082 * strictfp} modifier.
083 */
084 RELEASE_2,
085
086 /**
087 * The version recognized by the Java 2 Platform, Standard Edition,
088 * v 1.3.
089 *
090 * No major changes from {@code RELEASE_2}.
091 */
092 RELEASE_3,
093
094 /**
095 * The version recognized by the Java 2 Platform, Standard Edition,
096 * v 1.4.
097 *
098 * Added a simple assertion facility.
099 */
100 RELEASE_4,
101
102 /**
103 * The version recognized by the Java 2 Platform, Standard
104 * Edition 5.0.
105 *
106 * The language described in <i>The Java™ Language
107 * Specification, Third Edition</i>. First release to support
108 * generics, annotations, autoboxing, var-args, enhanced {@code
109 * for} loop, and hexadecimal floating-point literals.
110 */
111 RELEASE_5,
112
113 /**
114 * The version recognized by the Java Platform, Standard Edition
115 * 6.
116 *
117 * No major changes from {@code RELEASE_5}.
118 */
119 RELEASE_6,
120
121 /**
122 * The version recognized by the Java Platform, Standard Edition
123 * 7.
124 *
125 * @since 1.7
126 */
127 RELEASE_7;
128
129 // Note that when adding constants for newer releases, the
130 // behavior of latest() and latestSupported() must be updated too.
131
132 /**
133 * Returns the latest source version that can be modeled.
134 *
135 * @return the latest source version that can be modeled
136 */
137 public static SourceVersion latest() {
138 return RELEASE_7;
139 }
140
141 private static final SourceVersion latestSupported = getLatestSupported();
142
143 private static SourceVersion getLatestSupported() {
144 try {
145 String specVersion = System.getProperty("java.specification.version");
146 if ("1.7".equals(specVersion))
147 return RELEASE_7;
148 else if ("1.6".equals(specVersion))
149 return RELEASE_6;
150 } catch (SecurityException se) {}
151
152 return RELEASE_5;
153 }
154
155 /**
156 * Returns the latest source version fully supported by the
157 * current execution environment. {@code RELEASE_5} or later must
158 * be returned.
159 *
160 * @return the latest source version that is fully supported
161 */
162 public static SourceVersion latestSupported() {
163 return latestSupported;
164 }
165
166 /**
167 * Returns whether or not {@code name} is a syntactically valid
168 * identifier (simple name) or keyword in the latest source
169 * version. The method returns {@code true} if the name consists
170 * of an initial character for which {@link
171 * Character#isJavaIdentifierStart(int)} returns {@code true},
172 * followed only by characters for which {@link
173 * Character#isJavaIdentifierPart(int)} returns {@code true}.
174 * This pattern matches regular identifiers, keywords, and the
175 * literals {@code "true"}, {@code "false"}, and {@code "null"}.
176 * The method returns {@code false} for all other strings.
177 *
178 * @param name the string to check
179 * @return {@code true} if this string is a
180 * syntactically valid identifier or keyword, {@code false}
181 * otherwise.
182 */
183 public static boolean isIdentifier(CharSequence name) {
184 String id = name.toString();
185
186 if (id.length() == 0) {
187 return false;
188 }
189 int cp = id.codePointAt(0);
190 if (!Character.isJavaIdentifierStart(cp)) {
191 return false;
192 }
193 for (int i = Character.charCount(cp);
194 i < id.length();
195 i += Character.charCount(cp)) {
196 cp = id.codePointAt(i);
197 if (!Character.isJavaIdentifierPart(cp)) {
198 return false;
199 }
200 }
201 return true;
202 }
203
204 /**
205 * Returns whether or not {@code name} is a syntactically valid
206 * qualified name in the latest source version. Unlike {@link
207 * #isIdentifier isIdentifier}, this method returns {@code false}
208 * for keywords and literals.
209 *
210 * @param name the string to check
211 * @return {@code true} if this string is a
212 * syntactically valid name, {@code false} otherwise.
213 * @jls3 6.2 Names and Identifiers
214 */
215 public static boolean isName(CharSequence name) {
216 String id = name.toString();
217
218 for(String s : id.split("\\.", -1)) {
219 if (!isIdentifier(s) || isKeyword(s))
220 return false;
221 }
222 return true;
223 }
224
225 private final static Set<String> keywords;
226 static {
227 Set<String> s = new HashSet<String>();
228 String [] kws = {
229 "abstract", "continue", "for", "new", "switch",
230 "assert", "default", "if", "package", "synchronized",
231 "boolean", "do", "goto", "private", "this",
232 "break", "double", "implements", "protected", "throw",
233 "byte", "else", "import", "public", "throws",
234 "case", "enum", "instanceof", "return", "transient",
235 "catch", "extends", "int", "short", "try",
236 "char", "final", "interface", "static", "void",
237 "class", "finally", "long", "strictfp", "volatile",
238 "const", "float", "native", "super", "while",
239 // literals
240 "null", "true", "false"
241 };
242 for(String kw : kws)
243 s.add(kw);
244 keywords = Collections.unmodifiableSet(s);
245 }
246
247 /**
248 * Returns whether or not {@code s} is a keyword or literal in the
249 * latest source version.
250 *
251 * @param s the string to check
252 * @return {@code true} if {@code s} is a keyword or literal, {@code false} otherwise.
253 */
254 public static boolean isKeyword(CharSequence s) {
255 String keywordOrLiteral = s.toString();
256 return keywords.contains(keywordOrLiteral);
257 }
258 }