Skip to content

Commit b7b3b65

Browse files
committed
Make class file version more efficient and avoid experimental API on it.
1 parent 1e38dd0 commit b7b3b65

3 files changed

Lines changed: 70 additions & 149 deletions

File tree

byte-buddy-dep/src/main/java/net/bytebuddy/ClassFileVersion.java

Lines changed: 45 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import net.bytebuddy.build.HashCodeAndEqualsPlugin;
2121
import net.bytebuddy.description.type.TypeDescription;
2222
import net.bytebuddy.dynamic.ClassFileLocator;
23-
import net.bytebuddy.utility.OpenedClassReader;
2423
import net.bytebuddy.utility.nullability.MaybeNull;
2524
import org.objectweb.asm.Opcodes;
2625

@@ -160,6 +159,33 @@ public class ClassFileVersion implements Comparable<ClassFileVersion>, Serializa
160159
*/
161160
public static final ClassFileVersion JAVA_V23 = new ClassFileVersion(Opcodes.V23);
162161

162+
/**
163+
* An array of class file versions in their sorting order.
164+
*/
165+
private static final ClassFileVersion[] CLASS_FILE_VERSIONS = new ClassFileVersion[] {ClassFileVersion.JAVA_V1,
166+
ClassFileVersion.JAVA_V2,
167+
ClassFileVersion.JAVA_V3,
168+
ClassFileVersion.JAVA_V4,
169+
ClassFileVersion.JAVA_V5,
170+
ClassFileVersion.JAVA_V6,
171+
ClassFileVersion.JAVA_V7,
172+
ClassFileVersion.JAVA_V8,
173+
ClassFileVersion.JAVA_V9,
174+
ClassFileVersion.JAVA_V10,
175+
ClassFileVersion.JAVA_V11,
176+
ClassFileVersion.JAVA_V12,
177+
ClassFileVersion.JAVA_V13,
178+
ClassFileVersion.JAVA_V14,
179+
ClassFileVersion.JAVA_V15,
180+
ClassFileVersion.JAVA_V16,
181+
ClassFileVersion.JAVA_V17,
182+
ClassFileVersion.JAVA_V18,
183+
ClassFileVersion.JAVA_V19,
184+
ClassFileVersion.JAVA_V20,
185+
ClassFileVersion.JAVA_V21,
186+
ClassFileVersion.JAVA_V22,
187+
ClassFileVersion.JAVA_V23};
188+
163189
/**
164190
* A version locator for the executing JVM.
165191
*/
@@ -212,76 +238,20 @@ public static ClassFileVersion ofMinorMajor(int versionNumber) {
212238
* @return The appropriate class file version.
213239
*/
214240
public static ClassFileVersion ofJavaVersionString(String javaVersionString) {
215-
return ofJavaVersionString(javaVersionString, OpenedClassReader.EXPERIMENTAL);
216-
}
217-
218-
/**
219-
* Returns the Java class file by its representation by a version string in accordance to the formats known to <i>javac</i>.
220-
*
221-
* @param javaVersionString The Java version string.
222-
* @param experimental {@code true} if unknown version strings should be parsed as if they were known.
223-
* @return The appropriate class file version.
224-
*/
225-
public static ClassFileVersion ofJavaVersionString(String javaVersionString, boolean experimental) {
226-
if (javaVersionString.equals("1.1")) {
227-
return JAVA_V1;
228-
} else if (javaVersionString.equals("1.2")) {
229-
return JAVA_V2;
230-
} else if (javaVersionString.equals("1.3")) {
231-
return JAVA_V3;
232-
} else if (javaVersionString.equals("1.4")) {
233-
return JAVA_V4;
234-
} else if (javaVersionString.equals("1.5") || javaVersionString.equals("5")) {
235-
return JAVA_V5;
236-
} else if (javaVersionString.equals("1.6") || javaVersionString.equals("6")) {
237-
return JAVA_V6;
238-
} else if (javaVersionString.equals("1.7") || javaVersionString.equals("7")) {
239-
return JAVA_V7;
240-
} else if (javaVersionString.equals("1.8") || javaVersionString.equals("8")) {
241-
return JAVA_V8;
242-
} else if (javaVersionString.equals("1.9") || javaVersionString.equals("9")) {
243-
return JAVA_V9;
244-
} else if (javaVersionString.equals("1.10") || javaVersionString.equals("10")) {
245-
return JAVA_V10;
246-
} else if (javaVersionString.equals("1.11") || javaVersionString.equals("11")) {
247-
return JAVA_V11;
248-
} else if (javaVersionString.equals("1.12") || javaVersionString.equals("12")) {
249-
return JAVA_V12;
250-
} else if (javaVersionString.equals("1.13") || javaVersionString.equals("13")) {
251-
return JAVA_V13;
252-
} else if (javaVersionString.equals("1.14") || javaVersionString.equals("14")) {
253-
return JAVA_V14;
254-
} else if (javaVersionString.equals("1.15") || javaVersionString.equals("15")) {
255-
return JAVA_V15;
256-
} else if (javaVersionString.equals("1.16") || javaVersionString.equals("16")) {
257-
return JAVA_V16;
258-
} else if (javaVersionString.equals("1.17") || javaVersionString.equals("17")) {
259-
return JAVA_V17;
260-
} else if (javaVersionString.equals("1.18") || javaVersionString.equals("18")) {
261-
return JAVA_V18;
262-
} else if (javaVersionString.equals("1.19") || javaVersionString.equals("19")) {
263-
return JAVA_V19;
264-
} else if (javaVersionString.equals("1.20") || javaVersionString.equals("20")) {
265-
return JAVA_V20;
266-
} else if (javaVersionString.equals("1.21") || javaVersionString.equals("21")) {
267-
return JAVA_V21;
268-
} else if (javaVersionString.equals("1.22") || javaVersionString.equals("22")) {
269-
return JAVA_V22;
270-
} else if (javaVersionString.equals("1.23") || javaVersionString.equals("23")) {
271-
return JAVA_V23;
272-
} else {
273-
if (experimental) {
274-
try {
275-
int version = Integer.parseInt(javaVersionString.startsWith("1.")
276-
? javaVersionString.substring(2)
277-
: javaVersionString);
278-
if (version > 0) {
279-
return new ClassFileVersion(BASE_VERSION + version);
280-
}
281-
} catch (NumberFormatException ignored) {
241+
int index = javaVersionString.indexOf('.');
242+
try {
243+
int javaVersion;
244+
if (index == -1) {
245+
javaVersion = Integer.parseInt(javaVersionString);
246+
} else {
247+
javaVersion = Integer.parseInt(javaVersionString.substring(index + 1));
248+
if (Integer.parseInt(javaVersionString.substring(0, index)) != 1 || javaVersion > 8) {
249+
throw new IllegalArgumentException("Java versions with minor version must be of format 1.[1-7]: " + javaVersionString);
282250
}
283251
}
284-
throw new IllegalArgumentException("Unknown Java version string: " + javaVersionString);
252+
return ofJavaVersion(javaVersion);
253+
} catch (NumberFormatException exception) {
254+
throw new IllegalStateException("Failed to read Java version from: " + javaVersionString, exception);
285255
}
286256
}
287257

@@ -293,71 +263,12 @@ public static ClassFileVersion ofJavaVersionString(String javaVersionString, boo
293263
* @return A wrapper for the given Java class file version.
294264
*/
295265
public static ClassFileVersion ofJavaVersion(int javaVersion) {
296-
return ofJavaVersion(javaVersion, OpenedClassReader.EXPERIMENTAL);
297-
}
298-
299-
/**
300-
* Creates a class file version for a given major release of Java. Currently, all versions reaching from
301-
* Java 1 to Java 9 are supported.
302-
*
303-
* @param javaVersion The Java version.
304-
* @param experimental {@code true} if unknown Java versions should also be considered.
305-
* @return A wrapper for the given Java class file version.
306-
*/
307-
public static ClassFileVersion ofJavaVersion(int javaVersion, boolean experimental) {
308-
switch (javaVersion) {
309-
case 1:
310-
return JAVA_V1;
311-
case 2:
312-
return JAVA_V2;
313-
case 3:
314-
return JAVA_V3;
315-
case 4:
316-
return JAVA_V4;
317-
case 5:
318-
return JAVA_V5;
319-
case 6:
320-
return JAVA_V6;
321-
case 7:
322-
return JAVA_V7;
323-
case 8:
324-
return JAVA_V8;
325-
case 9:
326-
return JAVA_V9;
327-
case 10:
328-
return JAVA_V10;
329-
case 11:
330-
return JAVA_V11;
331-
case 12:
332-
return JAVA_V12;
333-
case 13:
334-
return JAVA_V13;
335-
case 14:
336-
return JAVA_V14;
337-
case 15:
338-
return JAVA_V15;
339-
case 16:
340-
return JAVA_V16;
341-
case 17:
342-
return JAVA_V17;
343-
case 18:
344-
return JAVA_V18;
345-
case 19:
346-
return JAVA_V19;
347-
case 20:
348-
return JAVA_V20;
349-
case 21:
350-
return JAVA_V21;
351-
case 22:
352-
return JAVA_V22;
353-
case 23:
354-
return JAVA_V23;
355-
default:
356-
if (experimental && javaVersion > 0) {
357-
return new ClassFileVersion(BASE_VERSION + javaVersion);
358-
} else {
359-
throw new IllegalArgumentException("Unknown Java version: " + javaVersion);
360-
}
266+
if (javaVersion < 1) {
267+
throw new IllegalArgumentException("Java version must be positive: " + javaVersion);
268+
} else if (javaVersion - 1 < CLASS_FILE_VERSIONS.length) {
269+
return CLASS_FILE_VERSIONS[javaVersion - 1];
270+
} else {
271+
return new ClassFileVersion(BASE_VERSION + javaVersion);
361272
}
362273
}
363274

byte-buddy-dep/src/test/java/net/bytebuddy/ClassFileVersionOtherTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,16 @@ public void testLatestVersion() throws Exception {
8888
assertThat(ClassFileVersion.latest().getMajorVersion(), is((short) value));
8989
}
9090

91+
@Test(expected = IllegalArgumentException.class)
92+
public void testNegativeVersion() throws Exception {
93+
ClassFileVersion.ofJavaVersion(0);
94+
}
95+
96+
@Test(expected = IllegalArgumentException.class)
97+
public void testOneDotTooNew() throws Exception {
98+
ClassFileVersion.ofJavaVersionString("1.9");
99+
}
100+
91101
@Test(expected = IllegalArgumentException.class)
92102
public void testIllegalClassFile() throws Exception {
93103
ClassFileVersion.ofClassFile(new byte[0]);

byte-buddy-dep/src/test/java/net/bytebuddy/ClassFileVersionTest.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,21 @@ public static Collection<Object[]> data() {
6666
{6, 6, Arrays.asList("1.6", "6"), Opcodes.V1_6, (short) 50, (short) 0, true, false, false},
6767
{7, 7, Arrays.asList("1.7", "7"), Opcodes.V1_7, (short) 51, (short) 0, true, true, false},
6868
{8, 8, Arrays.asList("1.8", "8"), Opcodes.V1_8, (short) 52, (short) 0, true, true, true},
69-
{9, 9, Arrays.asList("1.9", "9"), Opcodes.V9, (short) 53, (short) 0, true, true, true},
70-
{10, 10, Arrays.asList("1.10", "10"), Opcodes.V10, (short) 54, (short) 0, true, true, true},
71-
{11, 11, Arrays.asList("1.11", "11"), Opcodes.V11, (short) 55, (short) 0, true, true, true},
72-
{12, 12, Arrays.asList("1.12", "12"), Opcodes.V12, (short) 56, (short) 0, true, true, true},
73-
{13, 13, Arrays.asList("1.13", "13"), Opcodes.V13, (short) 57, (short) 0, true, true, true},
74-
{14, 14, Arrays.asList("1.14", "14"), Opcodes.V14, (short) 58, (short) 0, true, true, true},
75-
{15, 15, Arrays.asList("1.15", "15"), Opcodes.V15, (short) 59, (short) 0, true, true, true},
76-
{16, 16, Arrays.asList("1.16", "16"), Opcodes.V16, (short) 60, (short) 0, true, true, true},
77-
{17, 17, Arrays.asList("1.17", "17"), Opcodes.V17, (short) 61, (short) 0, true, true, true},
78-
{18, 18, Arrays.asList("1.18", "18"), Opcodes.V18, (short) 62, (short) 0, true, true, true},
79-
{19, 19, Arrays.asList("1.19", "19"), Opcodes.V19, (short) 63, (short) 0, true, true, true},
80-
{20, 20, Arrays.asList("1.20", "20"), Opcodes.V20, (short) 64, (short) 0, true, true, true},
81-
{21, 21, Arrays.asList("1.21", "21"), Opcodes.V21, (short) 65, (short) 0, true, true, true},
82-
{22, 22, Arrays.asList("1.22", "22"), Opcodes.V22, (short) 66, (short) 0, true, true, true},
83-
{23, 23, Arrays.asList("1.23", "23"), Opcodes.V23, (short) 67, (short) 0, true, true, true}
69+
{9, 9, Collections.singletonList("9"), Opcodes.V9, (short) 53, (short) 0, true, true, true},
70+
{10, 10, Collections.singletonList("10"), Opcodes.V10, (short) 54, (short) 0, true, true, true},
71+
{11, 11, Collections.singletonList("11"), Opcodes.V11, (short) 55, (short) 0, true, true, true},
72+
{12, 12, Collections.singletonList("12"), Opcodes.V12, (short) 56, (short) 0, true, true, true},
73+
{13, 13, Collections.singletonList("13"), Opcodes.V13, (short) 57, (short) 0, true, true, true},
74+
{14, 14, Collections.singletonList("14"), Opcodes.V14, (short) 58, (short) 0, true, true, true},
75+
{15, 15, Collections.singletonList("15"), Opcodes.V15, (short) 59, (short) 0, true, true, true},
76+
{16, 16, Collections.singletonList("16"), Opcodes.V16, (short) 60, (short) 0, true, true, true},
77+
{17, 17, Collections.singletonList("17"), Opcodes.V17, (short) 61, (short) 0, true, true, true},
78+
{18, 18, Collections.singletonList("18"), Opcodes.V18, (short) 62, (short) 0, true, true, true},
79+
{19, 19, Collections.singletonList("19"), Opcodes.V19, (short) 63, (short) 0, true, true, true},
80+
{20, 20, Collections.singletonList("20"), Opcodes.V20, (short) 64, (short) 0, true, true, true},
81+
{21, 21, Collections.singletonList("21"), Opcodes.V21, (short) 65, (short) 0, true, true, true},
82+
{22, 22, Collections.singletonList("22"), Opcodes.V22, (short) 66, (short) 0, true, true, true},
83+
{23, 23, Collections.singletonList("23"), Opcodes.V23, (short) 67, (short) 0, true, true, true}
8484
});
8585
}
8686

0 commit comments

Comments
 (0)