--- old/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java 2016-05-17 13:43:30.793508595 -0700 +++ new/src/java.compiler/share/classes/javax/lang/model/SourceVersion.java 2016-05-17 13:43:30.653508598 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ * 1.6: no changes * 1.7: diamond syntax, try-with-resources, etc. * 1.8: lambda expressions and default methods - * 9: To be determined + * 9: modules, small cleanups to 1.7 and 1.8 changes */ /** @@ -145,6 +145,9 @@ * The version recognized by the Java Platform, Standard Edition * 9. * + * Additions in this release include modules and removal of a + * single underscore from the set of legal identifier names. + * * @since 9 */ RELEASE_9; @@ -233,10 +236,10 @@ } /** - * Returns whether or not {@code name} is a syntactically valid - * qualified name in the latest source version. Unlike {@link - * #isIdentifier isIdentifier}, this method returns {@code false} - * for keywords and literals. + * Returns whether or not {@code name} is a syntactically valid + * qualified name in the latest source version. Unlike {@link + * #isIdentifier isIdentifier}, this method returns {@code false} + * for keywords and literals. * * @param name the string to check * @return {@code true} if this string is a @@ -244,10 +247,27 @@ * @jls 6.2 Names and Identifiers */ public static boolean isName(CharSequence name) { + return isName(name, latest()); + } + + /** + * Returns whether or not {@code name} is a syntactically valid + * qualified name in the given source version. Unlike {@link + * #isIdentifier isIdentifier}, this method returns {@code false} + * for keywords and literals. + * + * @param name the string to check + * @param version the version to use + * @return {@code true} if this string is a + * syntactically valid name, {@code false} otherwise. + * @jls 6.2 Names and Identifiers + * @since 9 + */ + public static boolean isName(CharSequence name, SourceVersion version) { String id = name.toString(); for(String s : id.split("\\.", -1)) { - if (!isIdentifier(s) || isKeyword(s)) + if (!isIdentifier(s) || isKeyword(s, version)) return false; } return true; @@ -268,7 +288,8 @@ "class", "finally", "long", "strictfp", "volatile", "const", "float", "native", "super", "while", // literals - "null", "true", "false" + "null", "true", "false", + "_" // keyword as of 9 }; for(String kw : kws) s.add(kw); @@ -276,8 +297,8 @@ } /** - * Returns whether or not {@code s} is a keyword or literal in the - * latest source version. + * Returns whether or not {@code s} is a keyword or literal in the + * latest source version. * * @param s the string to check * @return {@code true} if {@code s} is a keyword or literal, {@code false} otherwise. @@ -285,4 +306,22 @@ public static boolean isKeyword(CharSequence s) { return keywords.contains(s.toString()); } + + /** + * Returns whether or not {@code s} is a keyword or literal in the + * given source version. + * + * @param s the string to check + * @param version the version to use + * @return {@code true} if {@code s} is a keyword or literal, {@code false} otherwise. + * @since 9 + */ + public static boolean isKeyword(CharSequence s, SourceVersion version) { + String id = s.toString(); + if ("_".equals(id)) { + return version.compareTo(RELEASE_9) >= 0; + } else { + return keywords.contains(id); + } + } }