renamed constants and added bytecode tags

This commit is contained in:
Sander Hautvast 2020-11-09 11:25:42 +01:00
parent 61ca5f9a11
commit 7968d27814
36 changed files with 442 additions and 279 deletions

View file

@ -2,7 +2,7 @@ package nl.sander.beejava;
import nl.sander.beejava.api.BeeClass;
import nl.sander.beejava.constantpool.ConstantPool;
import nl.sander.beejava.constantpool.entry.ConstantPoolEntry;
import nl.sander.beejava.constantpool.entry.NodeConstant;
import nl.sander.beejava.util.ByteBuf;
import java.util.Set;
@ -28,7 +28,7 @@ public class Compiler {
buf.add(beeClass.getClassFileVersion().getMinor());
buf.add(beeClass.getClassFileVersion().getMajor());
Set<ConstantPoolEntry> constantTree = constantTreeCreator.createConstantTree(beeClass);
Set<NodeConstant> constantTree = constantTreeCreator.createConstantTree(beeClass);
ConstantPool constantPool = constantPoolCreator.createConstantPool(constantTree);
buf.add(constantPool.getBytes());

View file

@ -1,7 +1,7 @@
package nl.sander.beejava;
import nl.sander.beejava.constantpool.ConstantPool;
import nl.sander.beejava.constantpool.entry.ConstantPoolEntry;
import nl.sander.beejava.constantpool.entry.NodeConstant;
import java.util.Set;
@ -9,10 +9,11 @@ import java.util.Set;
* Transforms the hierachical constant tree into a flat datastructure. The walks the tree adding indexes to each element.
*/
public class ConstantPoolCreator {
private ConstantPool constantPool;
private int index;
private ConstantPool constantPool; // the constant pool that is being created
private int index; // the current index that will be assigned to a constant pool entry. It needs to be unique for each entry.
// References to other elements in the pool are made through indexes, so they have to be valid to guarantee that the class can be loaded by the JVM.
public ConstantPool createConstantPool(Set<ConstantPoolEntry> constantTree) {
public ConstantPool createConstantPool(Set<NodeConstant> constantTree) {
constantPool = new ConstantPool();
constantPool.add(null); // dummy element to align it's index with the indexes in the elements themselves
index = 0;
@ -20,26 +21,26 @@ public class ConstantPoolCreator {
return constantPool;
}
private void updateToplevelElements(Set<ConstantPoolEntry> children) {
for (ConstantPoolEntry child : children) {
private void updateToplevelElements(Set<NodeConstant> children) {
for (NodeConstant child : children) {
addToPool(child);
updateChildElements(child.getChildren());
// first the complete toplevel element including it's children, then next toplevel element
}
}
private void updateChildElements(Set<ConstantPoolEntry> children) {
private void updateChildElements(Set<NodeConstant> children) {
// first all direct children
for (ConstantPoolEntry child : children) {
for (NodeConstant child : children) {
addToPool(child);
}
// then further lineage
for (ConstantPoolEntry child : children) {
for (NodeConstant child : children) {
updateChildElements(child.getChildren());
}
}
private void addToPool(ConstantPoolEntry entry) {
private void addToPool(NodeConstant entry) {
index += 1;
entry.setIndex(index);
constantPool.add(entry);

View file

@ -18,7 +18,7 @@ import java.util.Set;
* also TODO make sure entries aren't duplicates
*/
public class ConstantTreeCreator {
private final Set<ConstantPoolEntry> constantTree = new LinkedHashSet<>();
private final Set<NodeConstant> constantTree = new LinkedHashSet<>();
private BeeClass beeClass;
/**
@ -28,7 +28,7 @@ public class ConstantTreeCreator {
* @param beeClass the Class object for which the constant pool needs to be created
* @return a Set of constant pool entries
*/
public Set<ConstantPoolEntry> createConstantTree(BeeClass beeClass) {
public Set<NodeConstant> createConstantTree(BeeClass beeClass) {
constantTree.clear();
this.beeClass = beeClass;
beeClass.getConstructors().forEach(this::updateConstantTree);
@ -55,23 +55,23 @@ public class ConstantTreeCreator {
}
private void addMethod(CodeLine codeline) {
constantTree.add(new MethodRefEntry(createClassName(codeline), createMethodNameAndType(codeline)));
constantTree.add(new ConstantMethodRef(createClassName(codeline), createMethodNameAndType(codeline)));
}
private void addField(CodeLine codeline) {
constantTree.add(new FieldRefEntry(createClassName(codeline), createFieldNameAndType(codeline)));
constantTree.add(new ConstantFieldRef(createClassName(codeline), createFieldNameAndType(codeline)));
}
private NameAndTypeEntry createMethodNameAndType(CodeLine codeline) {
return new NameAndTypeEntry(new Utf8Entry(codeline.getMethodName()), new Utf8Entry(codeline.getMethodSignature()));
private ConstantNameAndType createMethodNameAndType(CodeLine codeline) {
return new ConstantNameAndType(new ConstantUtf8(codeline.getMethodName()), new ConstantUtf8(codeline.getMethodSignature()));
}
private NameAndTypeEntry createFieldNameAndType(CodeLine codeline) {
return new NameAndTypeEntry(new Utf8Entry(codeline.getField().getName()), new Utf8Entry(TypeMapper.map(codeline.getField().getType())));
private ConstantNameAndType createFieldNameAndType(CodeLine codeline) {
return new ConstantNameAndType(new ConstantUtf8(codeline.getField().getName()), new ConstantUtf8(TypeMapper.map(codeline.getField().getType())));
}
private ClassEntry createClassName(CodeLine codeline) {
return new ClassEntry(new Utf8Entry(internalName(getNameOfClass(codeline))));
private ConstantClass createClassName(CodeLine codeline) {
return new ConstantClass(new ConstantUtf8(internalName(getNameOfClass(codeline))));
}
private String getNameOfClass(CodeLine codeline) {

View file

@ -1,14 +1,14 @@
package nl.sander.beejava.constantpool;
import nl.sander.beejava.constantpool.entry.ConstantPoolEntry;
import nl.sander.beejava.constantpool.entry.NodeConstant;
import java.util.ArrayList;
import java.util.List;
public class ConstantPool {
private final List<ConstantPoolEntry> entries=new ArrayList<>();
private final List<NodeConstant> entries=new ArrayList<>();
public int getIndex(ConstantPoolEntry entry){
public int getIndex(NodeConstant entry){
for (int i=0; i<entries.size(); i++){
if (entries.get(i)==entry){
return i+1;
@ -17,11 +17,7 @@ public class ConstantPool {
return -1;
}
public void add(int index, ConstantPoolEntry entry){
entries.add(index, entry);
}
public void add(ConstantPoolEntry entry){
public void add(NodeConstant entry){
entries.add(entry);
}

View file

@ -1,9 +1,9 @@
package nl.sander.beejava.constantpool.entry;
public class ClassEntry extends ConstantPoolEntry {
private final Utf8Entry name;
public class ConstantClass extends NodeConstant {
private final ConstantUtf8 name;
public ClassEntry(Utf8Entry name) {
public ConstantClass(ConstantUtf8 name) {
super(name);
this.name = name;
}
@ -18,4 +18,9 @@ public class ClassEntry extends ConstantPoolEntry {
"nameIndex=" + getNameIndex() +
'}';
}
@Override
public int getTag() {
return 7;
}
}

View file

@ -0,0 +1,14 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantDouble extends LeafConstant {
private final double doubleVal;
public ConstantDouble(double doubleVal) {
this.doubleVal = doubleVal;
}
@Override
public int getTag() {
return 6;
}
}

View file

@ -0,0 +1,20 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantDynamic extends NodeConstant {
private final int bootstrapMethodIndex; // TODO
private final ConstantNameAndType nameAndType;
public ConstantDynamic(int bootstrapMethodIndex, ConstantNameAndType nameAndType) {
this.bootstrapMethodIndex = bootstrapMethodIndex;
this.nameAndType = nameAndType;
}
@Override
public int getTag() {
return 17;
}
public int getNameAndTypeIndex(){
return nameAndType.getIndex();
}
}

View file

@ -0,0 +1,33 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantFieldRef extends NodeConstant {
private final ConstantClass constantClass;
private final ConstantNameAndType constantNameAndType;
public ConstantFieldRef(ConstantClass constantClass, ConstantNameAndType constantNameAndType) {
super(constantClass, constantNameAndType);
this.constantClass = constantClass;
this.constantNameAndType = constantNameAndType;
}
public int getClassIndex() {
return constantClass.getIndex();
}
public int getNameAndTypeIndex() {
return constantNameAndType.getIndex();
}
@Override
public String toString() {
return "FieldRefEntry{" +
"classIndex=" + getClassIndex() +
", nameAndTypeIndex=" + getNameAndTypeIndex() +
'}';
}
@Override
public int getTag() {
return 9;
}
}

View file

@ -1,9 +1,9 @@
package nl.sander.beejava.constantpool.entry;
public class FloatEntry extends LeafEntry {
public class ConstantFloat extends LeafConstant {
private final float floatVal;
public FloatEntry(float floatVal) {
public ConstantFloat(float floatVal) {
this.floatVal = floatVal;
}
@ -13,4 +13,9 @@ public class FloatEntry extends LeafEntry {
"floatVal=" + floatVal +
'}';
}
@Override
public int getTag() {
return 4;
}
}

View file

@ -1,9 +1,9 @@
package nl.sander.beejava.constantpool.entry;
public class IntEntry extends LeafEntry {
public class ConstantInteger extends LeafConstant {
private final int intVal;
public IntEntry(int integer) {
public ConstantInteger(int integer) {
this.intVal = integer;
}
@ -13,4 +13,9 @@ public class IntEntry extends LeafEntry {
"intVal=" + intVal +
'}';
}
@Override
public int getTag() {
return 3;
}
}

View file

@ -0,0 +1,25 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantInterfaceMethodRef extends NodeConstant {
private final ConstantClass constantClass;
private final ConstantNameAndType constantNameAndType;
public ConstantInterfaceMethodRef(ConstantClass constantClass, ConstantNameAndType constantNameAndType) {
super(constantClass, constantNameAndType);
this.constantClass = constantClass;
this.constantNameAndType = constantNameAndType;
}
public int getClassIndex(){
return constantClass.getIndex();
}
public int getNameAndTypeIndex(){
return constantNameAndType.getIndex();
}
@Override
public int getTag() {
return 11;
}
}

View file

@ -0,0 +1,26 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantInvokeDynamic extends NodeConstant {
private final int bootstrapMethodAttrIndex; //??
private final ConstantNameAndType constantNameAndType;
public ConstantInvokeDynamic(int bootstrapMethodAttrIndex, ConstantNameAndType constantNameAndType) {
this.bootstrapMethodAttrIndex = bootstrapMethodAttrIndex;
this.constantNameAndType = constantNameAndType;
}
@Override
public String toString() {
return "InvokeDynamicEntry{" +
"bootstrapMethodAttrIndex=" + bootstrapMethodAttrIndex +
", nameAndTypeIndex=" + constantNameAndType.getIndex() +
'}';
}
@Override
public int getTag() {
return 18;
}
}
//TODO implement later

View file

@ -1,10 +1,10 @@
package nl.sander.beejava.constantpool.entry;
public class LongEntry extends LeafEntry {
public class ConstantLong extends LeafConstant {
private final long longVal;
public LongEntry(long longVal) {
public ConstantLong(long longVal) {
this.longVal = longVal;
}
@ -14,4 +14,9 @@ public class LongEntry extends LeafEntry {
"longVal=" + longVal +
'}';
}
@Override
public int getTag() {
return 5;
}
}

View file

@ -0,0 +1,32 @@
package nl.sander.beejava.constantpool.entry;
//TODO implement later
public class ConstantMethodHandle extends NodeConstant {
private final int referenceKind;
// only 1 of these can be present:
private ConstantFieldRef constantFieldRef;
private ConstantMethodRef constantMethodRef;
private ConstantInterfaceMethodRef constantInterfaceMethodRef;
public ConstantMethodHandle(int referenceKind) {
this.referenceKind = referenceKind;
}
@Override
public String toString() {
return "MethodHandleEntry{" +
"referenceKind=" + referenceKind +
", referenceIndex=" + getReferenceIndex() +
'}';
}
private int getReferenceIndex() {
return 0; //TODO implement
}
@Override
public int getTag() {
return 15;
}
}

View file

@ -0,0 +1,25 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantMethodRef extends NodeConstant {
private final ConstantClass constantClass;
private final ConstantNameAndType constantNameAndType;
public ConstantMethodRef(ConstantClass constantClass, ConstantNameAndType constantNameAndType) {
super(constantClass, constantNameAndType);
this.constantClass = constantClass;
this.constantNameAndType = constantNameAndType;
}
public int getClassIndex() {
return constantClass.getIndex();
}
public int getNameAndTypeIndex() {
return constantNameAndType.getIndex();
}
@Override
public int getTag() {
return 10;
}
}

View file

@ -0,0 +1,21 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantMethodType extends NodeConstant {
private final ConstantUtf8 methodDescriptor;
public ConstantMethodType(ConstantUtf8 methodDescriptor) {
this.methodDescriptor = methodDescriptor;
}
@Override
public String toString() {
return "MethodTypeEntry{" +
"methodDescriptor=" + methodDescriptor +
'}';
}
@Override
public int getTag() {
return 16;
}
}

View file

@ -0,0 +1,16 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantModule extends NodeConstant {
private final ConstantUtf8 nameEntry;
public ConstantModule(ConstantUtf8 nameEntry) {
super(nameEntry);
this.nameEntry = nameEntry;
}
@Override
public int getTag() {
return 19;
}
}

View file

@ -1,10 +1,10 @@
package nl.sander.beejava.constantpool.entry;
public class NameAndTypeEntry extends ConstantPoolEntry {
private final Utf8Entry name;
private final Utf8Entry type;
public class ConstantNameAndType extends NodeConstant {
private final ConstantUtf8 name;
private final ConstantUtf8 type;
public NameAndTypeEntry(Utf8Entry name, Utf8Entry type) {
public ConstantNameAndType(ConstantUtf8 name, ConstantUtf8 type) {
super(name,type);
this.name = name;
this.type = type;
@ -26,4 +26,9 @@ public class NameAndTypeEntry extends ConstantPoolEntry {
", typeIndex=" + getTypeIndex() +
'}';
}
@Override
public int getTag() {
return 12;
}
}

View file

@ -0,0 +1,19 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantPackage extends NodeConstant {
private final ConstantUtf8 name;
public ConstantPackage(ConstantUtf8 name) {
super(name);
this.name = name;
}
public int getNameIndex() {
return name.getIndex();
}
@Override
public int getTag() {
return 20;
}
}

View file

@ -1,27 +0,0 @@
package nl.sander.beejava.constantpool.entry;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
public abstract class ConstantPoolEntry {
protected final Set<ConstantPoolEntry> children;
private int index;
protected ConstantPoolEntry(ConstantPoolEntry... children) {
this.children = new LinkedHashSet<>();
this.children.addAll(Arrays.asList(children)); // java8 way destroys order, not desastrous, but I like to preserve it.
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public Set<ConstantPoolEntry> getChildren() {
return children;
}
}

View file

@ -1,9 +1,9 @@
package nl.sander.beejava.constantpool.entry;
public class StringEntry extends ConstantPoolEntry {
private final Utf8Entry utf8;
public class ConstantString extends NodeConstant {
private final ConstantUtf8 utf8;
public StringEntry(Utf8Entry utf8) {
public ConstantString(ConstantUtf8 utf8) {
this.utf8 = utf8;
}
@ -17,4 +17,9 @@ public class StringEntry extends ConstantPoolEntry {
"utf8Index=" + getUtf8Index() +
'}';
}
@Override
public int getTag() {
return 8;
}
}

View file

@ -0,0 +1,25 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantUtf8 extends LeafConstant {
private final String value;
public ConstantUtf8(String utf8) {
this.value = utf8;
}
public String getUtf8() {
return value;
}
@Override
public String toString() {
return "Utf8Entry{" +
"value='" + value + '\'' +
'}';
}
@Override
public int getTag() {
return 1;
}
}

View file

@ -1,10 +0,0 @@
package nl.sander.beejava.constantpool.entry;
public class DoubleEntry extends LeafEntry {
private final double doubleVal;
public DoubleEntry(double doubleVal) {
this.doubleVal = doubleVal;
}
}

View file

@ -1,28 +0,0 @@
package nl.sander.beejava.constantpool.entry;
public class FieldRefEntry extends ConstantPoolEntry {
private final ClassEntry classEntry;
private final NameAndTypeEntry nameAndTypeEntry;
public FieldRefEntry(ClassEntry classEntry, NameAndTypeEntry nameAndTypeEntry) {
super(classEntry, nameAndTypeEntry);
this.classEntry = classEntry;
this.nameAndTypeEntry = nameAndTypeEntry;
}
public int getClassIndex() {
return classEntry.getIndex();
}
public int getNameAndTypeIndex() {
return nameAndTypeEntry.getIndex();
}
@Override
public String toString() {
return "FieldRefEntry{" +
"classIndex=" + getClassIndex() +
", nameAndTypeIndex=" + getNameAndTypeIndex() +
'}';
}
}

View file

@ -1,20 +0,0 @@
package nl.sander.beejava.constantpool.entry;
public class InterfaceMethodRefEntry extends ConstantPoolEntry {
private final ClassEntry classEntry;
private final NameAndTypeEntry nameAndTypeEntry;
public InterfaceMethodRefEntry(ClassEntry classEntry, NameAndTypeEntry nameAndTypeEntry) {
super(classEntry,nameAndTypeEntry);
this.classEntry = classEntry;
this.nameAndTypeEntry = nameAndTypeEntry;
}
public int getClassIndex(){
return classEntry.getIndex();
}
public int getNameAndTypeIndex(){
return nameAndTypeEntry.getIndex();
}
}

View file

@ -1,17 +0,0 @@
//package nl.sander.beejava.constantpool.entry;
//
//public class InvokeDynamicEntry extends ConstantPoolEntry {
// private final int bootstrapMethodAttrIndex; //??
// private final NameAndTypeEntry nameAndTypeEntry;
//
//
//
// @Override
// public String toString() {
// return "InvokeDynamicEntry{" +
// "bootstrapMethodAttrIndex=" + bootstrapMethodAttrIndex +
// ", nameAndTypeIndex=" + nameAndTypeIndex +
// '}';
// }
//}
//TODO implement later

View file

@ -3,9 +3,12 @@ package nl.sander.beejava.constantpool.entry;
import java.util.Collections;
import java.util.Set;
public class LeafEntry extends ConstantPoolEntry {
/**
* Is a constant without children
*/
public abstract class LeafConstant extends NodeConstant {
@Override
public Set<ConstantPoolEntry> getChildren() {
public Set<NodeConstant> getChildren() {
return Collections.emptySet();
}
}

View file

@ -1,21 +0,0 @@
//package nl.sander.beejava.constantpool.entry;
//
//public class MethodHandleEntry extends ConstantPoolEntry {
// private final int referenceKind;
// private final int referenceIndex;
//
// public MethodHandleEntry(int referenceKind, int referenceIndex) {
// this.referenceKind = referenceKind;
// this.referenceIndex = referenceIndex;
// }
//
// @Override
// public String toString() {
// return "MethodHandleEntry{" +
// "referenceKind=" + referenceKind +
// ", referenceIndex=" + referenceIndex +
// '}';
// }
//}
//TODO implement later

View file

@ -1,21 +0,0 @@
package nl.sander.beejava.constantpool.entry;
public class MethodRefEntry extends ConstantPoolEntry {
private final ClassEntry classEntry;
private final NameAndTypeEntry nameAndTypeEntry;
public MethodRefEntry(ClassEntry classEntry, NameAndTypeEntry nameAndTypeEntry) {
super(classEntry,nameAndTypeEntry);
this.classEntry = classEntry;
this.nameAndTypeEntry = nameAndTypeEntry;
}
public int getClassIndex() {
return classEntry.getIndex();
}
public int getNameAndTypeIndex() {
return nameAndTypeEntry.getIndex();
}
}

View file

@ -1,18 +0,0 @@
//package nl.sander.beejava.constantpool.entry;
//
//public class MethodTypeEntry extends ConstantPoolEntry {
// private final int descriptorIndex;
//
// public MethodTypeEntry(int descriptorIndex) {
// this.descriptorIndex = descriptorIndex;
// }
//
// @Override
// public String toString() {
// return "MethodTypeEntry{" +
// "descriptorIndex=" + descriptorIndex +
// '}';
// }
//}
//TODO implement when I know that this is

View file

@ -1,11 +0,0 @@
package nl.sander.beejava.constantpool.entry;
public class ModuleEntry extends ConstantPoolEntry {
private final Utf8Entry nameEntry;
public ModuleEntry(Utf8Entry nameEntry) {
super(nameEntry);
this.nameEntry = nameEntry;
}
}

View file

@ -0,0 +1,35 @@
package nl.sander.beejava.constantpool.entry;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
public abstract class NodeConstant {
protected final Set<NodeConstant> children; // TODO decide whether or not to keep this. Could also make getChildren abstract and make it return a new list every time
// TODO to save storage. getChildren should only be called once, so it is probably more efficient like that
private int index; // the index of the entry is not known until after creation of the complete tree, so cannot be final, but it should not be updated.
protected NodeConstant(NodeConstant... children) {
this.children = new LinkedHashSet<>();
this.children.addAll(Arrays.asList(children)); // java8 way destroys order, not desastrous, but I like to preserve it.
}
/*
* The tag that indicates the entry type in the bytecode.
* §4.4 Table 4.4-A. Constant pool tags
*/
public abstract int getTag();
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public Set<NodeConstant> getChildren() {
return children;
}
}

View file

@ -1,14 +0,0 @@
package nl.sander.beejava.constantpool.entry;
public class PackageEntry extends ConstantPoolEntry {
private final Utf8Entry name;
public PackageEntry(Utf8Entry name) {
super(name);
this.name = name;
}
public int getNameIndex() {
return name.getIndex();
}
}

View file

@ -1,20 +0,0 @@
package nl.sander.beejava.constantpool.entry;
public class Utf8Entry extends LeafEntry {
private final String stringVal;
public Utf8Entry(String utf8) {
this.stringVal = utf8;
}
public String getUtf8() {
return stringVal;
}
@Override
public String toString() {
return "Utf8Entry{" +
"stringVal='" + stringVal + '\'' +
'}';
}
}

View file

@ -20,45 +20,45 @@ public class ConstantTreeCreatorTests {
@Test // This is not a maintainable test
public void testMethodRefEntryForSuperConstructor() {
BeeClass classWithIntField = createEmptyClass();
Set<ConstantPoolEntry> constantTree = new ConstantTreeCreator().createConstantTree(classWithIntField);
Set<NodeConstant> constantTree = new ConstantTreeCreator().createConstantTree(classWithIntField);
assertEquals(1, constantTree.size());
ConstantPoolEntry superConstructor = constantTree.iterator().next();
NodeConstant superConstructor = constantTree.iterator().next();
assertEquals(MethodRefEntry.class, superConstructor.getClass());
MethodRefEntry methodRefEntry = (MethodRefEntry) superConstructor;
assertEquals(ConstantMethodRef.class, superConstructor.getClass());
ConstantMethodRef constantMethodRef = (ConstantMethodRef) superConstructor;
Set<ConstantPoolEntry> methodRefEntryChildren = methodRefEntry.getChildren();
Set<NodeConstant> methodRefEntryChildren = constantMethodRef.getChildren();
assertEquals(2, methodRefEntryChildren.size());
Iterator<ConstantPoolEntry> firstChildren = methodRefEntryChildren.iterator();
ConstantPoolEntry child1 = firstChildren.next();
assertEquals(ClassEntry.class, child1.getClass());
ClassEntry classEntry = (ClassEntry) child1;
Iterator<NodeConstant> firstChildren = methodRefEntryChildren.iterator();
NodeConstant child1 = firstChildren.next();
assertEquals(ConstantClass.class, child1.getClass());
ConstantClass constantClass = (ConstantClass) child1;
Set<ConstantPoolEntry> classEntryChildren = classEntry.getChildren();
Set<NodeConstant> classEntryChildren = constantClass.getChildren();
assertEquals(1, classEntryChildren.size());
ConstantPoolEntry child2 = classEntryChildren.iterator().next();
NodeConstant child2 = classEntryChildren.iterator().next();
assertEquals(Utf8Entry.class, child2.getClass());
Utf8Entry className = (Utf8Entry) child2;
assertEquals(ConstantUtf8.class, child2.getClass());
ConstantUtf8 className = (ConstantUtf8) child2;
assertEquals("java/lang/Object", className.getUtf8());
ConstantPoolEntry child3 = firstChildren.next();
assertEquals(NameAndTypeEntry.class, child3.getClass());
NameAndTypeEntry nameAndTypeEntry = (NameAndTypeEntry) child3;
NodeConstant child3 = firstChildren.next();
assertEquals(ConstantNameAndType.class, child3.getClass());
ConstantNameAndType constantNameAndType = (ConstantNameAndType) child3;
Set<ConstantPoolEntry> nameAndTypeEntryChildren = nameAndTypeEntry.getChildren();
Set<NodeConstant> nameAndTypeEntryChildren = constantNameAndType.getChildren();
assertEquals(2, nameAndTypeEntryChildren.size());
Iterator<ConstantPoolEntry> nameAndTypeChildrenIterator = nameAndTypeEntryChildren.iterator();
Iterator<NodeConstant> nameAndTypeChildrenIterator = nameAndTypeEntryChildren.iterator();
ConstantPoolEntry child4 = nameAndTypeChildrenIterator.next();
assertEquals(Utf8Entry.class, child4.getClass());
Utf8Entry name = (Utf8Entry) child4;
NodeConstant child4 = nameAndTypeChildrenIterator.next();
assertEquals(ConstantUtf8.class, child4.getClass());
ConstantUtf8 name = (ConstantUtf8) child4;
assertEquals("<init>", name.getUtf8());
ConstantPoolEntry child5 = nameAndTypeChildrenIterator.next();
assertEquals(Utf8Entry.class, child5.getClass());
Utf8Entry type = (Utf8Entry) child5;
NodeConstant child5 = nameAndTypeChildrenIterator.next();
assertEquals(ConstantUtf8.class, child5.getClass());
ConstantUtf8 type = (ConstantUtf8) child5;
assertEquals("()V", type.getUtf8());
}

View file

@ -0,0 +1,49 @@
package nl.sander.beejava.constantpool.entry;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* make sure tags were put in the code according to spec (§4.4)
*/
public class TagCorrectnessTest {
@Test
public void testSpec() {
assertEquals(7, classEntry().getTag());
assertEquals(9, fieldRef().getTag());
assertEquals(10, new ConstantMethodRef(classEntry(), nameAndType()).getTag());
assertEquals(11, new ConstantInterfaceMethodRef(classEntry(), nameAndType()).getTag());
assertEquals(8, new ConstantString(utf8()).getTag());
assertEquals(3, new ConstantInteger(0).getTag());
assertEquals(4, new ConstantFloat(0).getTag());
assertEquals(5, new ConstantLong(0).getTag());
assertEquals(6, new ConstantDouble(0).getTag());
assertEquals(12, nameAndType().getTag());
assertEquals(1, utf8().getTag());
assertEquals(15, new ConstantMethodHandle(0).getTag()); //TODO
assertEquals(16, new ConstantMethodType(utf8()).getTag()); //TODO
assertEquals(17, new ConstantDynamic(0, nameAndType()).getTag()); //TODO
assertEquals(18, new ConstantInvokeDynamic(0, nameAndType()).getTag()); //TODO
assertEquals(19, new ConstantModule(utf8()).getTag());
assertEquals(20, new ConstantPackage(utf8()).getTag());
}
private ConstantFieldRef fieldRef() {
return new ConstantFieldRef(classEntry(), nameAndType());
}
private ConstantNameAndType nameAndType() {
return new ConstantNameAndType(utf8(), utf8());
}
private ConstantClass classEntry() {
return new ConstantClass(utf8());
}
private ConstantUtf8 utf8() {
return new ConstantUtf8("");
}
}