Skip to content

Commit

Permalink
fix: support minor part in class version number
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Jul 4, 2023
1 parent 4d0b9e3 commit dc7bd12
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import io.github.skylot.raung.asm.impl.utils.RaungAsmException;
import io.github.skylot.raung.common.Directive;
import io.github.skylot.raung.common.RaungAccessFlags.Scope;
import io.github.skylot.raung.common.utils.JavaVersion;

import static io.github.skylot.raung.common.Directive.ANNOTATION;
import static io.github.skylot.raung.common.Directive.AUTO;
Expand Down Expand Up @@ -61,7 +62,22 @@ public static void process(Directive token, RaungParser parser, ClassData cw) {

private static void processVersion(RaungParser parser, ClassData classData) {
checkClassHeader(classData, VERSION);
classData.setVersion(parser.readInt());
int clsVersion;
String version = "";
try {
version = parser.readToken();
int point = version.indexOf('.');
if (point == -1) {
clsVersion = Integer.parseInt(version);
} else {
int major = Integer.parseInt(version.substring(0, point));
int minor = Integer.parseInt(version.substring(point + 1));
clsVersion = JavaVersion.getRaw(major, minor);
}
classData.setVersion(clsVersion);
} catch (Exception e) {
throw new RaungAsmException("Failed to parse class version number: " + version, e);
}
parser.lineEnd();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.skylot.raung.disasm.impl.utils;
package io.github.skylot.raung.common.utils;

import java.util.HashMap;
import java.util.Map;
Expand All @@ -7,7 +7,7 @@

public enum JavaVersion {
JAVA_1_0_2(45, "1.0.2"),
JAVA_1_1(3 << 16 | 45, "1.1"),
JAVA_1_1(getRaw(45, 3), "1.1"),
JAVA_1_2(46, "1.2"),
JAVA_1_3(47, "1.3"),
JAVA_1_4(48, "1.4"),
Expand All @@ -25,7 +25,20 @@ public enum JavaVersion {
JAVA_16(60, "16"),
JAVA_17(61, "17"),
JAVA_18(62, "18"),
JAVA_19(63, "19");
JAVA_19(63, "19"),
JAVA_20(64, "20"),
JAVA_21(65, "21");

private static final Map<Integer, JavaVersion> MAP;

static {
JavaVersion[] values = values();
Map<Integer, JavaVersion> map = new HashMap<>(values.length);
for (JavaVersion value : values) {
map.put(value.rawVersion, value);
}
MAP = map;
}

private final int rawVersion;
private final String name;
Expand All @@ -44,22 +57,23 @@ public String getName() {
}

public int getMajor() {
return rawVersion & 0xFFFF;
return getMajor(rawVersion);
}

public int getMinor() {
return (rawVersion & 0xFFFF0000) >> 16;
return getMinor(rawVersion);
}

private static final Map<Integer, JavaVersion> MAP;
public static int getMajor(int rawVersion) {
return rawVersion & 0xFFFF;
}

static {
JavaVersion[] values = values();
Map<Integer, JavaVersion> map = new HashMap<>(values.length);
for (JavaVersion value : values) {
map.put(value.rawVersion, value);
}
MAP = map;
public static int getMinor(int rawVersion) {
return (rawVersion & 0xFFFF0000) >> 16;
}

public static int getRaw(int major, int minor) {
return minor << 16 | major;
}

public static final int PREVIEW_VERSION = 0xFFFF0000;
Expand All @@ -70,14 +84,21 @@ public static boolean isPreview(int rawVersion) {

public static String getNameStr(int rawVersion) {
StringBuilder sb = new StringBuilder("Java ");
int major = getMajor(rawVersion);
boolean preview = isPreview(rawVersion);
int searchVersion = preview ? rawVersion & 0xFFFF : rawVersion;
int searchVersion = preview ? major : rawVersion;
JavaVersion version = MAP.get(searchVersion);
if (version != null) {
sb.append(version.name);
} else {
if (!preview) {
int minor = getMinor(rawVersion);
if (minor != 0) {
return getNameStr(getRaw(major, 0)) + " (with unknown minor: " + minor + ')';
}
}
// try approximation :)
int verDiff = searchVersion - JAVA_18.rawVersion;
int verDiff = major - getMajor(JAVA_18.rawVersion);
if (verDiff > 0) {
sb.append(18 + verDiff).append(" (approximated)");
} else {
Expand All @@ -90,6 +111,15 @@ public static String getNameStr(int rawVersion) {
return sb.toString();
}

public static String formatVersionNumber(int rawVersion) {
int major = getMajor(rawVersion);
int minor = getMinor(rawVersion);
if (minor == 0) {
return Integer.toString(major);
}
return major + "." + minor;
}

@Nullable
public static JavaVersion get(int rawVersion) {
return MAP.get(rawVersion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@

import io.github.skylot.raung.common.Directive;
import io.github.skylot.raung.common.RaungAccessFlags;
import io.github.skylot.raung.common.utils.JavaVersion;
import io.github.skylot.raung.disasm.impl.RaungDisasmBuilder;
import io.github.skylot.raung.disasm.impl.utils.JavaVersion;
import io.github.skylot.raung.disasm.impl.utils.RaungTypes;
import io.github.skylot.raung.disasm.impl.utils.RaungWriter;

Expand All @@ -36,7 +36,8 @@ public RaungClassVisitor(RaungDisasmBuilder args) {

@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
writer.add(Directive.VERSION.token()).space().add(version)
writer.add(Directive.VERSION.token()).space()
.add(JavaVersion.formatVersionNumber(version))
.add(" # ").add(JavaVersion.getNameStr(version));
writer.startLine(Directive.CLASS).add(RaungAccessFlags.format(access, CLASS)).add(name);
if (!superName.equals("java/lang/Object")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import org.junit.jupiter.api.Test;

import static io.github.skylot.raung.disasm.impl.utils.JavaVersion.JAVA_17;
import static io.github.skylot.raung.disasm.impl.utils.JavaVersion.JAVA_19;
import static io.github.skylot.raung.disasm.impl.utils.JavaVersion.JAVA_1_1;
import static io.github.skylot.raung.disasm.impl.utils.JavaVersion.JAVA_8;
import static io.github.skylot.raung.disasm.impl.utils.JavaVersion.PREVIEW_VERSION;
import static io.github.skylot.raung.disasm.impl.utils.JavaVersion.getNameStr;
import io.github.skylot.raung.common.utils.JavaVersion;

import static io.github.skylot.raung.common.utils.JavaVersion.JAVA_17;
import static io.github.skylot.raung.common.utils.JavaVersion.JAVA_1_1;
import static io.github.skylot.raung.common.utils.JavaVersion.JAVA_21;
import static io.github.skylot.raung.common.utils.JavaVersion.JAVA_8;
import static io.github.skylot.raung.common.utils.JavaVersion.PREVIEW_VERSION;
import static io.github.skylot.raung.common.utils.JavaVersion.getNameStr;
import static org.assertj.core.api.Assertions.assertThat;

class TestJavaVersion {
Expand All @@ -17,10 +19,12 @@ public void various() {
assertThat(getNameStr(JAVA_1_1.getRawVersion())).isEqualTo("Java 1.1");
assertThat(getNameStr(JAVA_8.getRawVersion())).isEqualTo("Java 8");
assertThat(getNameStr(JAVA_17.getRawVersion() | PREVIEW_VERSION)).isEqualTo("Java 17 preview");
assertThat(getNameStr(JAVA_19.getRawVersion() + 1)).isEqualTo("Java 20 (approximated)");
assertThat(getNameStr((JAVA_19.getRawVersion() + 2) | PREVIEW_VERSION)).isEqualTo("Java 21 (approximated) preview");
assertThat(getNameStr(JAVA_21.getRawVersion() + 1)).isEqualTo("Java 22 (approximated)");
assertThat(getNameStr((JAVA_21.getRawVersion() + 2) | PREVIEW_VERSION)).isEqualTo("Java 23 (approximated) preview");

assertThat(JAVA_1_1.getMajor()).isEqualTo(45);
assertThat(JAVA_1_1.getMinor()).isEqualTo(3);

assertThat(getNameStr(JavaVersion.getRaw(JAVA_17.getMajor(), 1))).isEqualTo("Java 17 (with unknown minor: 1)");
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.version 196653 # Java 1.1
.version 45.3 # Java 1.1
.class public final super b

.field public static a [[B
Expand Down

0 comments on commit dc7bd12

Please sign in to comment.