jdk-24/test/langtools/tools/javac/classfiles/ClassVersionChecker.java
Joe Darcy 75dc2f8518 8330182: Start of release updates for JDK 24
8330183: Add SourceVersion.RELEASE_24
8330184: Add source 24 and target 24 to javac

Reviewed-by: iris, vromero, asotona, dholmes
2024-06-06 16:01:57 +00:00

183 lines
6.0 KiB
Java

/*
* Copyright (c) 2012, 2024, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 7157626 8001112 8188870 8173382 8193290 8205619 8245586 8257453 8306586 8330184
* @summary Test major version for all legal combinations for -source and -target
* @author sgoel
*
* @modules jdk.compiler
*/
import java.io.*;
import java.nio.*;
import java.util.*;
import java.util.regex.*;
/*
* If not explicitly specified the latest source and latest target
* values are the defaults. If explicitly specified, the target value
* has to be greater than or equal to the source value.
*/
public class ClassVersionChecker {
private static enum Version {
EIGHT("8", 52),
NINE("9", 53),
TEN("10", 54),
ELEVEN("11", 55),
TWELVE("12", 56),
THIRTEEN("13", 57),
FOURTEEN("14", 58),
FIFTEEN("15", 59),
SIXTEEN("16", 60),
SEVENTEEN("17", 61),
EIGHTEEN("18", 62),
NINETEEN("19", 63),
TWENTY("20", 64),
TWENTY_ONE("21", 65),
TWENTY_TWO("22", 66),
TWENTY_THREE("23", 67),
TWENTY_FOUR("24", 68),
; // Reduce code churn when appending new constants
private Version(String release, int classFileVer) {
this.release = release;
this.classFileVer = classFileVer;
}
private final String release;
private final int classFileVer;
String release() {return release;}
int classFileVer() {return classFileVer;}
}
static final Version CURRENT;
static {
Version[] versions = Version.values();
int index = versions.length;
CURRENT = versions[index - 1];
}
int errors;
File javaFile = null;
public static void main(String[] args) throws Throwable {
new ClassVersionChecker().run();
}
void run() throws Exception {
writeTestFile();
/*
* Rules applicable for -source and -target combinations:
* 1. If both empty, version num is for the current release
* 2. If source is not empty and target is empty, version is
* based on the current release
* 3. If both non-empty, version is based on target
*/
test("", "", CURRENT.classFileVer());
for (Version source : Version.values()) {
test(source.release(), "", CURRENT.classFileVer()); // no target
for (Version target : Version.values()) {
if (target.compareTo(source) < 0)
continue; // Target < source not a valid set of arguments
else {
logMsg("Running for src = " + source + " target = "+ target +
" expected = " + target.classFileVer());
test(source.release(), target.release(), target.classFileVer());
}
}
}
if (errors > 0)
throw new Exception(errors + " errors found");
}
void test(String i, String j, int expected) {
File classFile = compileTestFile(i, j, javaFile);
short majorVer = getMajorVersion(classFile);
checkVersion(majorVer, expected);
}
void writeTestFile() throws IOException {
javaFile = new File("Test.java");
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(javaFile)));) {
out.println("class Test { ");
out.println(" public void foo() { }");
out.println("}");
} catch (IOException ioe) {
error("IOException while creating Test.java" + ioe);
}
}
File compileTestFile(String i, String j, File f) {
int rc = -1;
// Src and target are empty
if (i.isEmpty() && j.isEmpty() ) {
rc = compile("-g", f.getPath());
} else if( j.isEmpty()) { // target is empty
rc = compile("-source", i, "-g", f.getPath());
} else {
rc = compile("-source", i, "-target", j, "-g", f.getPath());
}
if (rc != 0)
throw new Error("compilation failed. rc=" + rc);
String path = f.getPath();
return new File(path.substring(0, path.length() - 5) + ".class");
}
int compile(String... args) {
return com.sun.tools.javac.Main.compile(args);
}
void logMsg (String str) {
System.out.println(str);
}
short getMajorVersion(File f) {
List<String> args = new ArrayList<String>();
short majorVer = 0;
try(DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(f)));) {
in.readInt();
in.readShort();
majorVer = in.readShort();
System.out.println("major version:" + majorVer);
} catch (IOException e) {
error("IOException while reading Test.class" + e);
}
return majorVer;
}
void checkVersion(short majorVer, int expected) {
if (majorVer != expected ) {
error("versions did not match, Expected: " + expected + "Got: " + majorVer);
}
}
void error(String msg) {
System.out.println("error: " + msg);
errors++;
}
}