8275308: Add valueOf(Runtime.Version) factory to SourceVersion

Reviewed-by: jjg
This commit is contained in:
Joe Darcy 2021-10-28 22:11:03 +00:00
parent c6339cb8a2
commit 48f3fcab51
2 changed files with 115 additions and 2 deletions
src/java.compiler/share/classes/javax/lang/model
test/langtools/tools/javac/processing/model

@ -492,4 +492,58 @@ public enum SourceVersion {
return false;
}
}
/**
* {@return the latest source version that is usable under the
* runtime version argument} If the runtime version's {@linkplain
* Runtime.Version#feature() feature} is greater than the feature
* of the {@linkplain #runtimeVersion() runtime version} of the
* {@linkplain #latest() latest source version}, an {@code
* IllegalArgumentException} is thrown.
*
* <p>Because the source versions of the Java programming language
* have so far followed a linear progression, only the feature
* component of a runtime version is queried to determine the
* mapping to a source version. If that linearity changes in the
* future, other components of the runtime version may influence
* the result.
*
* @apiNote
* An expression to convert from a string value, for example
* {@code "17"}, to the corresponding source version, {@code
* RELEASE_17}, is:
*
* <pre>{@code SourceVersion.valueOf(Runtime.Version.parse("17"))}</pre>
*
* @param rv runtime version to map to a source version
* @throws IllegalArgumentException if the feature of version
* argument is greater than the feature of the platform version.
* @since 18
*/
public static SourceVersion valueOf(Runtime.Version rv) {
// Could also implement this as a switch where a case was
// added with each new release.
return valueOf("RELEASE_" + rv.feature());
}
/**
* {@return the least runtime version that supports this source
* version; otherwise {@code null}} The returned runtime version
* has a {@linkplain Runtime.Version#feature() feature} large
* enough to support this source version and has no other elements
* set.
*
* Source versions greater than or equal to {@link RELEASE_6}
* have non-{@code null} results.
* @since 18
*/
public Runtime.Version runtimeVersion() {
// The javax.lang.model API was added in JDK 6; for now,
// limiting supported range to 6 and up.
if (this.compareTo(RELEASE_6) >= 0) {
return Runtime.Version.parse(Integer.toString(ordinal()));
} else {
return null;
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2021, 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
@ -23,7 +23,7 @@
/*
* @test
* @bug 7025809 8028543 6415644 8028544 8029942 8187951 8193291 8196551 8233096
* @bug 7025809 8028543 6415644 8028544 8029942 8187951 8193291 8196551 8233096 8275308
* @summary Test latest, latestSupported, underscore as keyword, etc.
* @author Joseph D. Darcy
* @modules java.compiler
@ -45,6 +45,8 @@ public class TestSourceVersion {
testRestrictedKeywords();
testVar();
testYield();
testValueOfRV();
testRuntimeVersion();
}
private static void testLatestSupported() {
@ -147,4 +149,61 @@ public class TestSourceVersion {
" on " + version);
}
}
/**
* Test that SourceVersion.valueOf() maps a Runtime.Version to a
* SourceVersion properly. The SourceVersion result is only a
* function of the feature() component of a Runtime.Version.
*/
private static void testValueOfRV() {
for (SourceVersion sv : SourceVersion.values()) {
if (sv == RELEASE_0) {
continue;
} else {
// Plain mapping; e.g. "17" -> RELEASE_17
String featureBase = Integer.toString(sv.ordinal());
checkValueOfResult(sv, featureBase);
// More populated runtime version, N.N
checkValueOfResult(sv, featureBase + "." + featureBase);
}
}
// Out of range test
try {
int latestFeature = SourceVersion.latest().runtimeVersion().feature();
SourceVersion.valueOf(Runtime.Version.parse(Integer.toString(latestFeature +1)));
throw new RuntimeException("Should not reach");
} catch (IllegalArgumentException iae) {
; // Expected
}
}
private static void checkValueOfResult(SourceVersion expected, String versionString) {
Runtime.Version rv = Runtime.Version.parse(versionString);
SourceVersion result = SourceVersion.valueOf(rv);
if (result != expected) {
throw new RuntimeException("Unexpected result " + result +
" of mapping Runtime.Version " + versionString +
" intead of " + expected);
}
}
private static void testRuntimeVersion() {
for (SourceVersion sv : SourceVersion.values()) {
Runtime.Version result = sv.runtimeVersion();
if (sv.compareTo(RELEASE_6) < 0) {
if (result != null) {
throw new RuntimeException("Unexpected result non-null " + result +
" as runtime version of " + sv);
}
} else {
Runtime.Version expected = Runtime.Version.parse(Integer.toString(sv.ordinal()));
if (!result.equals(expected)) {
throw new RuntimeException("Unexpected result " + result +
" as runtime version of " + sv);
}
}
}
}
}