Path: blob/master/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java
41159 views
/*1* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.lang.model;2627import java.util.Collections;28import java.util.Set;29import java.util.HashSet;3031/**32* Source versions of the Java programming language.33*34* See the appropriate edition of35* <cite>The Java Language Specification</cite>36* for information about a particular source version.37*38* <p>Note that additional source version constants will be added to39* model future releases of the language.40*41* @author Joseph D. Darcy42* @author Scott Seligman43* @author Peter von der Ahé44* @since 1.645*/46public enum SourceVersion {47/*48* Summary of language evolution49* 1.1: nested classes50* 1.2: strictfp51* 1.3: no changes52* 1.4: assert53* 1.5: annotations, generics, autoboxing, var-args...54* 1.6: no changes55* 1.7: diamond syntax, try-with-resources, etc.56* 1.8: lambda expressions and default methods57* 9: modules, small cleanups to 1.7 and 1.8 changes58* 10: local-variable type inference (var)59* 11: local-variable syntax for lambda parameters60* 12: no changes (switch expressions in preview)61* 13: no changes (switch expressions and text blocks in preview)62* 14: switch expressions (pattern matching and records in63* preview, text blocks in preview again)64* 15: text blocks (records and pattern matching in preview again)65*/6667/**68* The original version.69*70* The language described in71* <cite>The Java Language Specification, First Edition</cite>.72*/73RELEASE_0,7475/**76* The version recognized by the Java Platform 1.1.77*78* The language is {@code RELEASE_0} augmented with nested classes as described in the 1.1 update to79* <cite>The Java Language Specification, First Edition</cite>.80*/81RELEASE_1,8283/**84* The version recognized by the Java 2 Platform, Standard Edition,85* v 1.2.86*87* The language described in88* <cite>The Java Language Specification,89* Second Edition</cite>, which includes the {@code90* strictfp} modifier.91*/92RELEASE_2,9394/**95* The version recognized by the Java 2 Platform, Standard Edition,96* v 1.3.97*98* No major changes from {@code RELEASE_2}.99*/100RELEASE_3,101102/**103* The version recognized by the Java 2 Platform, Standard Edition,104* v 1.4.105*106* Added a simple assertion facility.107*/108RELEASE_4,109110/**111* The version recognized by the Java 2 Platform, Standard112* Edition 5.0.113*114* The language described in115* <cite>The Java Language Specification,116* Third Edition</cite>. First release to support117* generics, annotations, autoboxing, var-args, enhanced {@code118* for} loop, and hexadecimal floating-point literals.119*/120RELEASE_5,121122/**123* The version recognized by the Java Platform, Standard Edition124* 6.125*126* No major changes from {@code RELEASE_5}.127*/128RELEASE_6,129130/**131* The version recognized by the Java Platform, Standard Edition132* 7.133*134* Additions in this release include, diamond syntax for135* constructors, {@code try}-with-resources, strings in switch,136* binary literals, and multi-catch.137* @since 1.7138*/139RELEASE_7,140141/**142* The version recognized by the Java Platform, Standard Edition143* 8.144*145* Additions in this release include lambda expressions and default methods.146* @since 1.8147*/148RELEASE_8,149150/**151* The version recognized by the Java Platform, Standard Edition152* 9.153*154* Additions in this release include modules and removal of a155* single underscore from the set of legal identifier names.156*157* @since 9158*/159RELEASE_9,160161/**162* The version recognized by the Java Platform, Standard Edition163* 10.164*165* Additions in this release include local-variable type inference166* ({@code var}).167*168* @since 10169*/170RELEASE_10,171172/**173* The version recognized by the Java Platform, Standard Edition174* 11.175*176* Additions in this release include local-variable syntax for177* lambda parameters.178*179* @since 11180*/181RELEASE_11,182183/**184* The version recognized by the Java Platform, Standard Edition185* 12.186*187* @since 12188*/189RELEASE_12,190191/**192* The version recognized by the Java Platform, Standard Edition193* 13.194*195* @since 13196*/197RELEASE_13,198199/**200* The version recognized by the Java Platform, Standard Edition201* 14.202*203* Additions in this release include switch expressions.204*205* @since 14206*/207RELEASE_14,208209/**210* The version recognized by the Java Platform, Standard Edition211* 15.212*213* Additions in this release include text blocks.214*215* @since 15216*/217RELEASE_15,218219/**220* The version recognized by the Java Platform, Standard Edition221* 16.222*223* Additions in this release include pattern matching for {@code224* instanceof} and records.225*226* @since 16227*/228RELEASE_16,229230/**231* The version recognized by the Java Platform, Standard Edition232* 17.233*234* Additions in this release include sealed classes and235* restoration of always-strict floating-point semantics.236*237* @since 17238*/239RELEASE_17;240241// Note that when adding constants for newer releases, the242// behavior of latest() and latestSupported() must be updated too.243244/**245* {@return the latest source version that can be modeled}246*/247public static SourceVersion latest() {248return RELEASE_17;249}250251private static final SourceVersion latestSupported = getLatestSupported();252253/*254* The integer version to enum constant mapping implemented by255* this method assumes the JEP 322: "Time-Based Release256* Versioning" scheme is in effect. This scheme began in JDK257* 10. If the JDK versioning scheme is revised, this method may258* need to be updated accordingly.259*/260private static SourceVersion getLatestSupported() {261int intVersion = Runtime.version().feature();262return (intVersion >= 11) ?263valueOf("RELEASE_" + Math.min(17, intVersion)):264RELEASE_10;265}266267/**268* {@return the latest source version fully supported by the269* current execution environment} {@code RELEASE_9} or later must270* be returned.271*272* @apiNote This method is included alongside {@link latest} to273* allow identification of situations where the language model API274* is running on a platform version different than the latest275* version modeled by the API. One way that sort of situation can276* occur is if an IDE or similar tool is using the API to model277* source version <i>N</i> while running on platform version278* (<i>N</i> - 1). Running in this configuration is279* supported by the API. Running an API on platform versions280* earlier than (<i>N</i> - 1) or later than <i>N</i>281* may or may not work as an implementation detail. If an282* annotation processor was generating code to run under the283* current execution environment, the processor should only use284* platform features up to the {@code latestSupported} release,285* which may be earlier than the {@code latest} release.286*/287public static SourceVersion latestSupported() {288return latestSupported;289}290291/**292* Returns whether or not {@code name} is a syntactically valid293* identifier (simple name) or keyword in the latest source294* version. The method returns {@code true} if the name consists295* of an initial character for which {@link296* Character#isJavaIdentifierStart(int)} returns {@code true},297* followed only by characters for which {@link298* Character#isJavaIdentifierPart(int)} returns {@code true}.299* This pattern matches regular identifiers, keywords, restricted300* keywords, restricted identifiers and the literals {@code "true"},301* {@code "false"}, {@code "null"}.302*303* The method returns {@code false} for all other strings.304*305* @param name the string to check306* @return {@code true} if this string is a307* syntactically valid identifier or keyword, {@code false}308* otherwise.309*310* @jls 3.8 Identifiers311*/312public static boolean isIdentifier(CharSequence name) {313String id = name.toString();314315if (id.length() == 0) {316return false;317}318int cp = id.codePointAt(0);319if (!Character.isJavaIdentifierStart(cp)) {320return false;321}322for (int i = Character.charCount(cp);323i < id.length();324i += Character.charCount(cp)) {325cp = id.codePointAt(i);326if (!Character.isJavaIdentifierPart(cp)) {327return false;328}329}330return true;331}332333/**334* Returns whether or not {@code name} is a syntactically valid335* qualified name in the latest source version.336*337* Syntactically, a qualified name is a sequence of identifiers338* separated by period characters ("{@code .}"). This method339* splits the input string into period-separated segments and340* applies checks to each segment in turn.341*342* Unlike {@link #isIdentifier isIdentifier}, this method returns343* {@code false} for keywords, boolean literals, and the null344* literal in any segment.345*346* This method returns {@code true} for <i>restricted347* keywords</i> and <i>restricted identifiers</i>.348*349* @param name the string to check350* @return {@code true} if this string is a351* syntactically valid name, {@code false} otherwise.352* @jls 3.9 Keywords353* @jls 6.2 Names and Identifiers354*/355public static boolean isName(CharSequence name) {356return isName(name, latest());357}358359/**360* Returns whether or not {@code name} is a syntactically valid361* qualified name in the given source version.362*363* Syntactically, a qualified name is a sequence of identifiers364* separated by period characters ("{@code .}"). This method365* splits the input string into period-separated segments and366* applies checks to each segment in turn.367*368* Unlike {@link #isIdentifier isIdentifier}, this method returns369* {@code false} for keywords, boolean literals, and the null370* literal in any segment.371*372* This method returns {@code true} for <i>restricted373* keywords</i> and <i>restricted identifiers</i>.374*375* @param name the string to check376* @param version the version to use377* @return {@code true} if this string is a378* syntactically valid name, {@code false} otherwise.379* @jls 3.9 Keywords380* @jls 6.2 Names and Identifiers381* @since 9382*/383public static boolean isName(CharSequence name, SourceVersion version) {384String id = name.toString();385386for(String s : id.split("\\.", -1)) {387if (!isIdentifier(s) || isKeyword(s, version))388return false;389}390return true;391}392393/**394* Returns whether or not {@code s} is a keyword, boolean literal,395* or null literal in the latest source version.396* This method returns {@code false} for <i>restricted397* keywords</i> and <i>restricted identifiers</i>.398*399* @param s the string to check400* @return {@code true} if {@code s} is a keyword, or boolean401* literal, or null literal, {@code false} otherwise.402* @jls 3.9 Keywords403* @jls 3.10.3 Boolean Literals404* @jls 3.10.8 The Null Literal405*/406public static boolean isKeyword(CharSequence s) {407return isKeyword(s, latest());408}409410/**411* Returns whether or not {@code s} is a keyword, boolean literal,412* or null literal in the given source version.413* This method returns {@code false} for <i>restricted414* keywords</i> and <i>restricted identifiers</i>.415*416* @param s the string to check417* @param version the version to use418* @return {@code true} if {@code s} is a keyword, or boolean419* literal, or null literal, {@code false} otherwise.420* @jls 3.9 Keywords421* @jls 3.10.3 Boolean Literals422* @jls 3.10.8 The Null Literal423* @since 9424*/425public static boolean isKeyword(CharSequence s, SourceVersion version) {426String id = s.toString();427switch(id) {428// A trip through history429case "strictfp":430return version.compareTo(RELEASE_2) >= 0;431432case "assert":433return version.compareTo(RELEASE_4) >= 0;434435case "enum":436return version.compareTo(RELEASE_5) >= 0;437438case "_":439return version.compareTo(RELEASE_9) >= 0;440441// case "non-sealed": can be added once it is a keyword only442// dependent on release and not also preview features being443// enabled.444445// Keywords common across versions446447// Modifiers448case "public": case "protected": case "private":449case "abstract": case "static": case "final":450case "transient": case "volatile": case "synchronized":451case "native":452453// Declarations454case "class": case "interface": case "extends":455case "package": case "throws": case "implements":456457// Primitive types and void458case "boolean": case "byte": case "char":459case "short": case "int": case "long":460case "float": case "double":461case "void":462463// Control flow464case "if": case "else":465case "try": case "catch": case "finally":466case "do": case "while":467case "for": case "continue":468case "switch": case "case": case "default":469case "break": case "throw": case "return":470471// Other keywords472case "this": case "new": case "super":473case "import": case "instanceof":474475// Forbidden!476case "goto": case "const":477478// literals479case "null": case "true": case "false":480return true;481482default:483return false;484}485}486}487488489