From 78940c44697082f300bc2bb44699653fadb43836 Mon Sep 17 00:00:00 2001 From: Sander Hautvast Date: Thu, 16 Jul 2020 19:18:29 +0200 Subject: [PATCH] added java bytecode reader (not complete yet) --- .../nl/sander/jsontoy2/java/ClassObject.java | 124 ++++++++++++++ .../nl/sander/jsontoy2/java/ClassParser.java | 152 ++++++++++++++++++ .../java/nl/sander/jsontoy2/java/Field.java | 44 +++++ .../java/constantpool/ClassEntry.java | 16 ++ .../java/constantpool/ConstantPoolEntry.java | 5 + .../java/constantpool/DoubleEntry.java | 16 ++ .../java/constantpool/FieldRefEntry.java | 27 ++++ .../java/constantpool/FloatEntry.java | 16 ++ .../jsontoy2/java/constantpool/IntEntry.java | 16 ++ .../constantpool/InterfaceMethodRefEntry.java | 19 +++ .../java/constantpool/InvokeDynamicEntry.java | 19 +++ .../jsontoy2/java/constantpool/LongEntry.java | 17 ++ .../java/constantpool/MethodHandleEntry.java | 19 +++ .../java/constantpool/MethodRefEntry.java | 19 +++ .../java/constantpool/MethodTypeEntry.java | 16 ++ .../java/constantpool/NameAndType.java | 19 +++ .../java/constantpool/NameAndTypeEntry.java | 27 ++++ .../java/constantpool/StringEntry.java | 16 ++ .../jsontoy2/java/constantpool/Utf8Entry.java | 21 +++ .../sander/jsontoy2/java/ClassParserTest.java | 23 +++ 20 files changed, 631 insertions(+) create mode 100644 src/main/java/nl/sander/jsontoy2/java/ClassObject.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/ClassParser.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/Field.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/ClassEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/ConstantPoolEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/DoubleEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/FieldRefEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/FloatEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/IntEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/InterfaceMethodRefEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/InvokeDynamicEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/LongEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/MethodHandleEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/MethodRefEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/MethodTypeEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/NameAndType.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/NameAndTypeEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/StringEntry.java create mode 100644 src/main/java/nl/sander/jsontoy2/java/constantpool/Utf8Entry.java create mode 100644 src/test/java/nl/sander/jsontoy2/java/ClassParserTest.java diff --git a/src/main/java/nl/sander/jsontoy2/java/ClassObject.java b/src/main/java/nl/sander/jsontoy2/java/ClassObject.java new file mode 100644 index 0000000..39933bd --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/ClassObject.java @@ -0,0 +1,124 @@ +package nl.sander.jsontoy2.java; + +import nl.sander.jsontoy2.java.constantpool.*; + +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + + +public class ClassObject { + + private int constantPoolCount; + private ConstantPoolEntry[] constantPool; + private int constantPoolIndex = 0; + + public int getConstantPoolCount() { + return constantPoolCount; + } + + public String toString() { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < constantPoolCount - 1; i++) { + ConstantPoolEntry entry = constantPool[i]; + builder.append(entry.toString()); + builder.append(String.format("%n")); + } + return builder.toString(); + } + + private void add(ConstantPoolEntry entry) { + constantPool[constantPoolIndex++] = entry; + } + + public Set getFields() { + return Arrays.stream(constantPool) + .filter(e -> e instanceof FieldRefEntry) + .map(FieldRefEntry.class::cast) + .map(f -> { + NameAndType nat = getNameAndType(f); + return new Field(nat.getName(), nat.getType()); + }) + .collect(Collectors.toSet()); + } + + private NameAndType getNameAndType(FieldRefEntry f) { + NameAndTypeEntry natEntry = (NameAndTypeEntry) constantPool[f.getNameAndTypeIndex() - 1]; + return new NameAndType(getUtf8(natEntry.getNameIndex()), getUtf8(natEntry.getTypeIndex())); + } + + private String getUtf8(short index) { + return ((Utf8Entry) constantPool[index - 1]).getUtf8(); + } + + public static class Builder { + + private final ClassObject classObject = new ClassObject<>(); + + public ClassObject build() { + return classObject; + } + + public Builder constantPoolCount(int constantPoolCount) { + classObject.constantPoolCount = constantPoolCount; + classObject.constantPool = new ConstantPoolEntry[constantPoolCount]; + return this; + } + + public void constantPoolEntry(String utf8) { + classObject.add(new Utf8Entry(utf8)); + } + + public void constantPoolEntry(int i) { + classObject.add(new IntEntry(i)); + } + + public void constantPoolEntry(float f) { + classObject.add(new FloatEntry(f)); + } + + public void constantPoolEntry(long f) { + classObject.add(new LongEntry(f)); + } + + public void constantPoolEntry(double d) { + classObject.add(new DoubleEntry(d)); + } + + public void constantPoolClassEntry(short nameIndex) { + classObject.add(new ClassEntry(nameIndex)); + } + + public void constantPoolStringEntry(short utf8Index) { + classObject.add(new StringEntry(utf8Index)); + } + + public void constantPoolFieldRefEntry(short classIndex, short nameAndTypeIndex) { + classObject.add(new FieldRefEntry(classIndex, nameAndTypeIndex)); + } + + public void constantPoolMethodRefEntry(short classIndex, short nameAndTypeIndex) { + classObject.add(new MethodRefEntry(classIndex, nameAndTypeIndex)); + } + + public void constantPoolInterfaceMethodRefEntry(short classIndex, short nameAndTypeIndex) { + classObject.add(new InterfaceMethodRefEntry(classIndex, nameAndTypeIndex)); + } + + public void constantPoolNameAndTypeEntry(short nameIndex, short typeIndex) { + classObject.add(new NameAndTypeEntry(nameIndex, typeIndex)); + } + + public void constantPoolMethodHandleEntry(short referenceKind, short referenceIndex) { + classObject.add(new MethodHandleEntry(referenceKind, referenceIndex)); + } + + public void constantPoolMethodTypeEntry(short descriptorIndex) { + classObject.add(new MethodTypeEntry(descriptorIndex)); + } + + public void constantPoolInvokeDynamicEntry(short bootstrapMethodAttrIndex, short nameAndTypeIndex) { + classObject.add(new InvokeDynamicEntry(bootstrapMethodAttrIndex, nameAndTypeIndex)); + } + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/ClassParser.java b/src/main/java/nl/sander/jsontoy2/java/ClassParser.java new file mode 100644 index 0000000..96d27fa --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/ClassParser.java @@ -0,0 +1,152 @@ +package nl.sander.jsontoy2.java; + +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +public class ClassParser { + + public ClassObject parse(Class type) { + DataInputStream in = new DataInputStream(new BufferedInputStream(type.getResourceAsStream(getResourceName(type)))); + expect(in, 0xCAFEBABE); + ClassObject.Builder builder = new ClassObject.Builder<>(); + skip(in, 4); //skip version + int constantPoolCount = readShort(in); + builder.constantPoolCount(constantPoolCount); + for (int i = 1; i < constantPoolCount; i++) { + readConstantPoolEntry(in, builder); + } + return builder.build(); + } + + private void readConstantPoolEntry(DataInputStream in, ClassObject.Builder builder) { + byte tag = readByte(in); + switch (tag) { + case 1: readUtf8(in, builder); + break; + case 2: throw new IllegalStateException("2: invalid classpool tag"); + case 3: builder.constantPoolEntry(readInt(in)); + break; + case 4: builder.constantPoolEntry(readFloat(in)); + break; + case 5: builder.constantPoolEntry(readLong(in)); + break; + case 6: builder.constantPoolEntry(readDouble(in)); + break; + case 7: builder.constantPoolClassEntry(readShort(in)); + break; + case 8: builder.constantPoolStringEntry(readShort(in)); + break; + case 9: builder.constantPoolFieldRefEntry(readShort(in), readShort(in)); + break; + case 10: builder.constantPoolMethodRefEntry(readShort(in), readShort(in)); + break; + case 11: builder.constantPoolInterfaceMethodRefEntry(readShort(in), readShort(in)); + break; + case 12: builder.constantPoolNameAndTypeEntry(readShort(in), readShort(in)); + break; + case 15: builder.constantPoolMethodHandleEntry(readShort(in), readShort(in)); + break; + case 16: builder.constantPoolMethodTypeEntry(readShort(in)); + break; + case 18: builder.constantPoolInvokeDynamicEntry(readShort(in), readShort(in)); + break; + } + } + + private void readUtf8(DataInputStream in, ClassObject.Builder builder) { + short length = readShort(in); + String utf8 = readString(in, length); + builder.constantPoolEntry(utf8); + } + + private String readString(DataInputStream in, short length) { + try { + byte[] bytes = in.readNBytes(length); + return new String(bytes, StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException(); + } + } + + private long skip(InputStream in, long bytecount) { + try { + return in.skip(bytecount); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private byte readByte(DataInputStream in) { + try { + return in.readByte(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private short readShort(DataInputStream in) { + try { + return in.readShort(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private int readInt(DataInputStream in) { + try { + return in.readInt(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private float readFloat(DataInputStream in) { + try { + return in.readFloat(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private long readLong(DataInputStream in) { + try { + return in.readLong(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private double readDouble(DataInputStream in) { + try { + return in.readDouble(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void expect(DataInputStream in, int expected) { + try { + int i = in.readInt(); + if (i != expected) { + throw new IllegalStateException("class file not valid"); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private String getResourceName(Class type) { + StringBuilder typeName = new StringBuilder("/" + type.getName()); + + for (int i = 0; i < typeName.length(); i++) { + if (typeName.charAt(i) == '.') { + typeName.setCharAt(i, '/'); + } + } + typeName.append(".class"); + return typeName.toString(); + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/Field.java b/src/main/java/nl/sander/jsontoy2/java/Field.java new file mode 100644 index 0000000..f451698 --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/Field.java @@ -0,0 +1,44 @@ +package nl.sander.jsontoy2.java; + +import java.util.Objects; + +public class Field { + + private final String name; + private final String type; + + public Field(String name, String type) { + this.name = name; + this.type = type; + } + + public String getName() { + return name; + } + + public String getType() { + return type; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Field field = (Field) o; + return name.equals(field.name) && + type.equals(field.type); + } + + @Override + public int hashCode() { + return Objects.hash(name, type); + } + + @Override + public String toString() { + return "Field{" + + "name='" + name + '\'' + + ", type='" + type + '\'' + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/ClassEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/ClassEntry.java new file mode 100644 index 0000000..a7b48a1 --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/ClassEntry.java @@ -0,0 +1,16 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class ClassEntry extends ConstantPoolEntry { + private final short nameIndex; + + public ClassEntry(short nameIndex) { + this.nameIndex = nameIndex; + } + + @Override + public String toString() { + return "ClassEntry{" + + "nameIndex=" + nameIndex + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/ConstantPoolEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/ConstantPoolEntry.java new file mode 100644 index 0000000..30f4035 --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/ConstantPoolEntry.java @@ -0,0 +1,5 @@ +package nl.sander.jsontoy2.java.constantpool; + +public abstract class ConstantPoolEntry { + +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/DoubleEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/DoubleEntry.java new file mode 100644 index 0000000..04f25fe --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/DoubleEntry.java @@ -0,0 +1,16 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class DoubleEntry extends ConstantPoolEntry { + private final double doubleVal; + + public DoubleEntry(double doubleVal) { + this.doubleVal = doubleVal; + } + + @Override + public String toString() { + return "DoubleEntry{" + + "doubleVal=" + doubleVal + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/FieldRefEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/FieldRefEntry.java new file mode 100644 index 0000000..65a6234 --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/FieldRefEntry.java @@ -0,0 +1,27 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class FieldRefEntry extends ConstantPoolEntry { + private final short classIndex; + private final short nameAndTypeIndex; + + public FieldRefEntry(short classIndex, short nameAndTypeIndex) { + this.classIndex = classIndex; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + public short getClassIndex() { + return classIndex; + } + + public short getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + @Override + public String toString() { + return "FieldRefEntry{" + + "classIndex=" + classIndex + + ", nameAndTypeIndex=" + nameAndTypeIndex + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/FloatEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/FloatEntry.java new file mode 100644 index 0000000..e89fd71 --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/FloatEntry.java @@ -0,0 +1,16 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class FloatEntry extends ConstantPoolEntry { + private final float floatVal; + + public FloatEntry(float floatVal) { + this.floatVal = floatVal; + } + + @Override + public String toString() { + return "FloatEntry{" + + "floatVal=" + floatVal + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/IntEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/IntEntry.java new file mode 100644 index 0000000..3a471e3 --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/IntEntry.java @@ -0,0 +1,16 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class IntEntry extends ConstantPoolEntry { + private final int intVal; + + public IntEntry(int integer) { + this.intVal = integer; + } + + @Override + public String toString() { + return "IntEntry{" + + "intVal=" + intVal + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/InterfaceMethodRefEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/InterfaceMethodRefEntry.java new file mode 100644 index 0000000..a95802a --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/InterfaceMethodRefEntry.java @@ -0,0 +1,19 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class InterfaceMethodRefEntry extends ConstantPoolEntry { + private final short classIndex; + private final short nameAndTypeIndex; + + public InterfaceMethodRefEntry(short classIndex, short nameAndTypeIndex) { + this.classIndex = classIndex; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public String toString() { + return "InterfaceMethodRefEntry{" + + "classIndex=" + classIndex + + ", nameAndTypeIndex=" + nameAndTypeIndex + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/InvokeDynamicEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/InvokeDynamicEntry.java new file mode 100644 index 0000000..30074c3 --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/InvokeDynamicEntry.java @@ -0,0 +1,19 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class InvokeDynamicEntry extends ConstantPoolEntry { + private final short bootstrapMethodAttrIndex; + private final short nameAndTypeIndex; + + public InvokeDynamicEntry(short bootstrapMethodAttrIndex, short nameAndTypeIndex) { + this.bootstrapMethodAttrIndex = bootstrapMethodAttrIndex; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public String toString() { + return "InvokeDynamicEntry{" + + "bootstrapMethodAttrIndex=" + bootstrapMethodAttrIndex + + ", nameAndTypeIndex=" + nameAndTypeIndex + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/LongEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/LongEntry.java new file mode 100644 index 0000000..d7b8932 --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/LongEntry.java @@ -0,0 +1,17 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class LongEntry extends ConstantPoolEntry { + + private final long longVal; + + public LongEntry(long longVal) { + this.longVal = longVal; + } + + @Override + public String toString() { + return "LongEntry{" + + "longVal=" + longVal + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/MethodHandleEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/MethodHandleEntry.java new file mode 100644 index 0000000..d1d8a4e --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/MethodHandleEntry.java @@ -0,0 +1,19 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class MethodHandleEntry extends ConstantPoolEntry { + private final short referenceKind; + private final short referenceIndex; + + public MethodHandleEntry(short referenceKind, short referenceIndex) { + this.referenceKind = referenceKind; + this.referenceIndex = referenceIndex; + } + + @Override + public String toString() { + return "MethodHandleEntry{" + + "referenceKind=" + referenceKind + + ", referenceIndex=" + referenceIndex + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/MethodRefEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/MethodRefEntry.java new file mode 100644 index 0000000..2463385 --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/MethodRefEntry.java @@ -0,0 +1,19 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class MethodRefEntry extends ConstantPoolEntry { + private final short classIndex; + private final short nameAndTypeIndex; + + public MethodRefEntry(short classIndex, short nameAndTypeIndex) { + this.classIndex = classIndex; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + @Override + public String toString() { + return "MethodRefEntry{" + + "classIndex=" + classIndex + + ", nameAndTypeIndex=" + nameAndTypeIndex + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/MethodTypeEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/MethodTypeEntry.java new file mode 100644 index 0000000..bf4b87e --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/MethodTypeEntry.java @@ -0,0 +1,16 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class MethodTypeEntry extends ConstantPoolEntry { + private final short descriptorIndex; + + public MethodTypeEntry(short descriptorIndex) { + this.descriptorIndex = descriptorIndex; + } + + @Override + public String toString() { + return "MethodTypeEntry{" + + "descriptorIndex=" + descriptorIndex + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/NameAndType.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/NameAndType.java new file mode 100644 index 0000000..2e0bc85 --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/NameAndType.java @@ -0,0 +1,19 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class NameAndType { + private final String name; + private final String type; + + public NameAndType(String name, String type) { + this.name = name; + this.type = type; + } + + public String getName() { + return name; + } + + public String getType() { + return type; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/NameAndTypeEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/NameAndTypeEntry.java new file mode 100644 index 0000000..c9130cf --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/NameAndTypeEntry.java @@ -0,0 +1,27 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class NameAndTypeEntry extends ConstantPoolEntry { + private final short nameIndex; + private final short typeIndex; + + public NameAndTypeEntry(short nameIndex, short typeIndex) { + this.nameIndex = nameIndex; + this.typeIndex = typeIndex; + } + + public short getNameIndex() { + return nameIndex; + } + + public short getTypeIndex() { + return typeIndex; + } + + @Override + public String toString() { + return "NameAndTypeEntry{" + + "nameIndex=" + nameIndex + + ", typeIndex=" + typeIndex + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/StringEntry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/StringEntry.java new file mode 100644 index 0000000..c4b0e6f --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/StringEntry.java @@ -0,0 +1,16 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class StringEntry extends ConstantPoolEntry { + private final short utf8Index; + + public StringEntry(short utf8Index) { + this.utf8Index = utf8Index; + } + + @Override + public String toString() { + return "StringEntry{" + + "utf8Index=" + utf8Index + + '}'; + } +} diff --git a/src/main/java/nl/sander/jsontoy2/java/constantpool/Utf8Entry.java b/src/main/java/nl/sander/jsontoy2/java/constantpool/Utf8Entry.java new file mode 100644 index 0000000..8bf2971 --- /dev/null +++ b/src/main/java/nl/sander/jsontoy2/java/constantpool/Utf8Entry.java @@ -0,0 +1,21 @@ +package nl.sander.jsontoy2.java.constantpool; + +public class Utf8Entry extends ConstantPoolEntry { + private final String stringVal; + + public Utf8Entry(String utf8) { + this.stringVal = utf8; + } + + + public String getUtf8() { + return stringVal; + } + + @Override + public String toString() { + return "Utf8Entry{" + + "stringVal='" + stringVal + '\'' + + '}'; + } +} diff --git a/src/test/java/nl/sander/jsontoy2/java/ClassParserTest.java b/src/test/java/nl/sander/jsontoy2/java/ClassParserTest.java new file mode 100644 index 0000000..d63a788 --- /dev/null +++ b/src/test/java/nl/sander/jsontoy2/java/ClassParserTest.java @@ -0,0 +1,23 @@ +package nl.sander.jsontoy2.java; + +import org.junit.jupiter.api.Test; + +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ClassParserTest { + + private int field; + + @Test + public void testReadClass() { + ClassObject object = new ClassParser().parse(ClassParserTest.class); + assertEquals(Set.of(new Field("field", "I")), object.getFields()); + } + + // if not included, field is not in the compiled code. + public int getField() { + return field; + } +}