mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
6415644: Make javax.lang.model.SourceVersion more informative
Reviewed-by: jjg
This commit is contained in:
parent
e568099980
commit
8c88656e09
2 changed files with 144 additions and 35 deletions
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -55,7 +55,7 @@ public enum SourceVersion {
|
||||||
* 1.6: no changes
|
* 1.6: no changes
|
||||||
* 1.7: diamond syntax, try-with-resources, etc.
|
* 1.7: diamond syntax, try-with-resources, etc.
|
||||||
* 1.8: lambda expressions and default methods
|
* 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 @@ public enum SourceVersion {
|
||||||
* The version recognized by the Java Platform, Standard Edition
|
* The version recognized by the Java Platform, Standard Edition
|
||||||
* 9.
|
* 9.
|
||||||
*
|
*
|
||||||
|
* Additions in this release include modules and removal of a
|
||||||
|
* single underscore from the set of legal identifier names.
|
||||||
|
*
|
||||||
* @since 9
|
* @since 9
|
||||||
*/
|
*/
|
||||||
RELEASE_9;
|
RELEASE_9;
|
||||||
|
@ -233,10 +236,10 @@ public enum SourceVersion {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not {@code name} is a syntactically valid
|
* Returns whether or not {@code name} is a syntactically valid
|
||||||
* qualified name in the latest source version. Unlike {@link
|
* qualified name in the latest source version. Unlike {@link
|
||||||
* #isIdentifier isIdentifier}, this method returns {@code false}
|
* #isIdentifier isIdentifier}, this method returns {@code false}
|
||||||
* for keywords and literals.
|
* for keywords, boolean literals, and the null literal.
|
||||||
*
|
*
|
||||||
* @param name the string to check
|
* @param name the string to check
|
||||||
* @return {@code true} if this string is a
|
* @return {@code true} if this string is a
|
||||||
|
@ -244,45 +247,115 @@ public enum SourceVersion {
|
||||||
* @jls 6.2 Names and Identifiers
|
* @jls 6.2 Names and Identifiers
|
||||||
*/
|
*/
|
||||||
public static boolean isName(CharSequence name) {
|
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, boolean literals, and the null literal.
|
||||||
|
*
|
||||||
|
* @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();
|
String id = name.toString();
|
||||||
|
|
||||||
for(String s : id.split("\\.", -1)) {
|
for(String s : id.split("\\.", -1)) {
|
||||||
if (!isIdentifier(s) || isKeyword(s))
|
if (!isIdentifier(s) || isKeyword(s, version))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static Set<String> keywords;
|
/**
|
||||||
static {
|
* Returns whether or not {@code s} is a keyword, boolean literal,
|
||||||
Set<String> s = new HashSet<>();
|
* or null literal in the latest source version.
|
||||||
String [] kws = {
|
*
|
||||||
"abstract", "continue", "for", "new", "switch",
|
* @param s the string to check
|
||||||
"assert", "default", "if", "package", "synchronized",
|
* @return {@code true} if {@code s} is a keyword, or boolean
|
||||||
"boolean", "do", "goto", "private", "this",
|
* literal, or null literal, {@code false} otherwise.
|
||||||
"break", "double", "implements", "protected", "throw",
|
* @jls 3.9 Keywords
|
||||||
"byte", "else", "import", "public", "throws",
|
* @jls 3.10.3 Boolean Literals
|
||||||
"case", "enum", "instanceof", "return", "transient",
|
* @jls 3.10.7 The Null Literal
|
||||||
"catch", "extends", "int", "short", "try",
|
*/
|
||||||
"char", "final", "interface", "static", "void",
|
public static boolean isKeyword(CharSequence s) {
|
||||||
"class", "finally", "long", "strictfp", "volatile",
|
return isKeyword(s, latest());
|
||||||
"const", "float", "native", "super", "while",
|
|
||||||
// literals
|
|
||||||
"null", "true", "false"
|
|
||||||
};
|
|
||||||
for(String kw : kws)
|
|
||||||
s.add(kw);
|
|
||||||
keywords = Collections.unmodifiableSet(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether or not {@code s} is a keyword or literal in the
|
* Returns whether or not {@code s} is a keyword, boolean literal,
|
||||||
* latest source version.
|
* or null literal in the given source version.
|
||||||
*
|
*
|
||||||
* @param s the string to check
|
* @param s the string to check
|
||||||
* @return {@code true} if {@code s} is a keyword or literal, {@code false} otherwise.
|
* @param version the version to use
|
||||||
|
* @return {@code true} if {@code s} is a keyword, or boolean
|
||||||
|
* literal, or null literal, {@code false} otherwise.
|
||||||
|
* @jls 3.9 Keywords
|
||||||
|
* @jls 3.10.3 Boolean Literals
|
||||||
|
* @jls 3.10.7 The Null Literal
|
||||||
|
* @since 9
|
||||||
*/
|
*/
|
||||||
public static boolean isKeyword(CharSequence s) {
|
public static boolean isKeyword(CharSequence s, SourceVersion version) {
|
||||||
return keywords.contains(s.toString());
|
String id = s.toString();
|
||||||
|
switch(id) {
|
||||||
|
// A trip through history
|
||||||
|
case "strictfp":
|
||||||
|
return version.compareTo(RELEASE_2) >= 0;
|
||||||
|
|
||||||
|
case "assert":
|
||||||
|
return version.compareTo(RELEASE_4) >= 0;
|
||||||
|
|
||||||
|
case "enum":
|
||||||
|
return version.compareTo(RELEASE_5) >= 0;
|
||||||
|
|
||||||
|
case "_":
|
||||||
|
return version.compareTo(RELEASE_9) >= 0;
|
||||||
|
|
||||||
|
// Keywords common across versions
|
||||||
|
|
||||||
|
// Modifiers
|
||||||
|
case "public": case "protected": case "private":
|
||||||
|
case "abstract": case "static": case "final":
|
||||||
|
case "transient": case "volatile": case "synchronized":
|
||||||
|
case "native":
|
||||||
|
|
||||||
|
// Declarations
|
||||||
|
case "class": case "interface": case "extends":
|
||||||
|
case "package": case "throws": case "implements":
|
||||||
|
|
||||||
|
// Primitive types and void
|
||||||
|
case "boolean": case "byte": case "char":
|
||||||
|
case "short": case "int": case "long":
|
||||||
|
case "float": case "double":
|
||||||
|
case "void":
|
||||||
|
|
||||||
|
// Control flow
|
||||||
|
case "if": case "else":
|
||||||
|
case "try": case "catch": case "finally":
|
||||||
|
case "do": case "while":
|
||||||
|
case "for": case "continue":
|
||||||
|
case "switch": case "case": case "default":
|
||||||
|
case "break": case "throw": case "return":
|
||||||
|
|
||||||
|
// Other keywords
|
||||||
|
case "this": case "new": case "super":
|
||||||
|
case "import": case "instanceof":
|
||||||
|
|
||||||
|
// Forbidden!
|
||||||
|
case "goto": case "const":
|
||||||
|
|
||||||
|
// literals
|
||||||
|
case "null": case "true": case "false":
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -23,13 +23,14 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 7025809 8028543
|
* @bug 7025809 8028543 6415644
|
||||||
* @summary Test latest and latestSupported
|
* @summary Test latest, latestSupported, underscore as keyword, etc.
|
||||||
* @author Joseph D. Darcy
|
* @author Joseph D. Darcy
|
||||||
* @modules java.compiler
|
* @modules java.compiler
|
||||||
* jdk.compiler
|
* jdk.compiler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
import javax.lang.model.SourceVersion;
|
import javax.lang.model.SourceVersion;
|
||||||
import static javax.lang.model.SourceVersion.*;
|
import static javax.lang.model.SourceVersion.*;
|
||||||
|
|
||||||
|
@ -38,10 +39,45 @@ import static javax.lang.model.SourceVersion.*;
|
||||||
*/
|
*/
|
||||||
public class TestSourceVersion {
|
public class TestSourceVersion {
|
||||||
public static void main(String... args) {
|
public static void main(String... args) {
|
||||||
|
testLatestSupported();
|
||||||
|
testVersionVaryingKeywords();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void testLatestSupported() {
|
||||||
if (SourceVersion.latest() != RELEASE_9 ||
|
if (SourceVersion.latest() != RELEASE_9 ||
|
||||||
SourceVersion.latestSupported() != RELEASE_9)
|
SourceVersion.latestSupported() != RELEASE_9)
|
||||||
throw new RuntimeException("Unexpected release value(s) found:\n" +
|
throw new RuntimeException("Unexpected release value(s) found:\n" +
|
||||||
"latest:\t" + SourceVersion.latest() + "\n" +
|
"latest:\t" + SourceVersion.latest() + "\n" +
|
||||||
"latestSupported:\t" + SourceVersion.latestSupported());
|
"latestSupported:\t" + SourceVersion.latestSupported());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void testVersionVaryingKeywords() {
|
||||||
|
Map<String, SourceVersion> keyWordStart =
|
||||||
|
Map.of("strictfp", RELEASE_2,
|
||||||
|
"assert", RELEASE_4,
|
||||||
|
"enum", RELEASE_5,
|
||||||
|
"_", RELEASE_9);
|
||||||
|
|
||||||
|
for (Map.Entry<String, SourceVersion> entry : keyWordStart.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
SourceVersion value = entry.getValue();
|
||||||
|
|
||||||
|
check(true, isKeyword(key), "keyword", latest());
|
||||||
|
check(false, isName(key), "name", latest());
|
||||||
|
|
||||||
|
for(SourceVersion version : SourceVersion.values()) {
|
||||||
|
boolean isKeyword = version.compareTo(value) >= 0;
|
||||||
|
|
||||||
|
check(isKeyword, isKeyword(key, version), "keyword", version);
|
||||||
|
check(!isKeyword, isName(key, version), "name", version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void check(boolean result, boolean expected,
|
||||||
|
String message, SourceVersion version) {
|
||||||
|
if (result != expected) {
|
||||||
|
throw new RuntimeException("Unexpected " + message + "-ness of _ on " + version);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue