added java bytecode reader (not complete yet)
This commit is contained in:
parent
fd62bc9167
commit
78940c4469
20 changed files with 631 additions and 0 deletions
124
src/main/java/nl/sander/jsontoy2/java/ClassObject.java
Normal file
124
src/main/java/nl/sander/jsontoy2/java/ClassObject.java
Normal file
|
|
@ -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<T> {
|
||||||
|
|
||||||
|
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<Field> 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<T> {
|
||||||
|
|
||||||
|
private final ClassObject<T> classObject = new ClassObject<>();
|
||||||
|
|
||||||
|
public ClassObject<T> build() {
|
||||||
|
return classObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
152
src/main/java/nl/sander/jsontoy2/java/ClassParser.java
Normal file
152
src/main/java/nl/sander/jsontoy2/java/ClassParser.java
Normal file
|
|
@ -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 <T> ClassObject<T> parse(Class<T> type) {
|
||||||
|
DataInputStream in = new DataInputStream(new BufferedInputStream(type.getResourceAsStream(getResourceName(type))));
|
||||||
|
expect(in, 0xCAFEBABE);
|
||||||
|
ClassObject.Builder<T> 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 <T> void readConstantPoolEntry(DataInputStream in, ClassObject.Builder<T> 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 <T> String getResourceName(Class<T> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/main/java/nl/sander/jsontoy2/java/Field.java
Normal file
44
src/main/java/nl/sander/jsontoy2/java/Field.java
Normal file
|
|
@ -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 + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package nl.sander.jsontoy2.java.constantpool;
|
||||||
|
|
||||||
|
public abstract class ConstantPoolEntry {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/test/java/nl/sander/jsontoy2/java/ClassParserTest.java
Normal file
23
src/test/java/nl/sander/jsontoy2/java/ClassParserTest.java
Normal file
|
|
@ -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<ClassParserTest> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue