started adding support for methods
This commit is contained in:
parent
a1e78f5ed9
commit
ab4662f86e
24 changed files with 260 additions and 175 deletions
|
|
@ -1,9 +1,8 @@
|
||||||
package nl.sander.beejava;
|
package nl.sander.beejava;
|
||||||
|
|
||||||
import nl.sander.beejava.api.BeeClass;
|
|
||||||
import nl.sander.beejava.constantpool.ConstantPool;
|
import nl.sander.beejava.constantpool.ConstantPool;
|
||||||
import nl.sander.beejava.constantpool.entry.ConstantPoolEntry;
|
import nl.sander.beejava.constantpool.entry.ConstantPoolEntry;
|
||||||
import nl.sander.beejava.flags.ClassAccessFlag;
|
import nl.sander.beejava.flags.AccessFlags;
|
||||||
import nl.sander.beejava.util.ByteBuf;
|
import nl.sander.beejava.util.ByteBuf;
|
||||||
|
|
||||||
public class BytecodeGenerator {
|
public class BytecodeGenerator {
|
||||||
|
|
@ -23,19 +22,20 @@ public class BytecodeGenerator {
|
||||||
private byte[] generate() {
|
private byte[] generate() {
|
||||||
ByteBuf buf = new ByteBuf();
|
ByteBuf buf = new ByteBuf();
|
||||||
buf.addU8(0xCA, 0xFE, 0xBA, 0xBE);
|
buf.addU8(0xCA, 0xFE, 0xBA, 0xBE);
|
||||||
buf.addU16(compiledClass.getBeeClass().getClassFileVersion().getMinor());
|
buf.addU16(compiledClass.getSource().getClassFileVersion().getMinor());
|
||||||
buf.addU16(compiledClass.getBeeClass().getClassFileVersion().getMajor());
|
buf.addU16(compiledClass.getSource().getClassFileVersion().getMajor());
|
||||||
|
|
||||||
|
|
||||||
ConstantPool constantPool = constantPoolCreator.createConstantPool(compiledClass.getConstantTree());
|
ConstantPool constantPool = constantPoolCreator.createConstantPool(compiledClass.getConstantTree());
|
||||||
|
|
||||||
buf.addU16(constantPool.getLength());
|
buf.addU16(constantPool.getLength());
|
||||||
buf.addU8(constantPool.getBytes());
|
constantPool.addTo(buf);
|
||||||
buf.addU16(ClassAccessFlag.getSum(compiledClass.getBeeClass().getAccessFlags()));
|
buf.addU16(AccessFlags.combine(compiledClass.getSource().getAccessFlags()));
|
||||||
buf.addU16(compiledClass.geThisIndex());
|
buf.addU16(compiledClass.geThisIndex());
|
||||||
buf.addU16(compiledClass.getSuperIndex());
|
buf.addU16(compiledClass.getSuperIndex());
|
||||||
buf.addU16(compiledClass.getInterfaces().size());
|
buf.addU16(compiledClass.getInterfaces().size());
|
||||||
compiledClass.getInterfaces().forEach(interfase -> buf.addU16(interfase.getIndex()));
|
compiledClass.getInterfaces().forEach(interfase -> buf.addU16(interfase.getIndex()));
|
||||||
|
buf.addU16(compiledClass.getFields().size());
|
||||||
|
compiledClass.getFields().forEach(fieldInfo -> fieldInfo.addBytes(buf));
|
||||||
|
|
||||||
int x = 1;
|
int x = 1;
|
||||||
for (ConstantPoolEntry e : constantPool) {
|
for (ConstantPoolEntry e : constantPool) {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ import nl.sander.beejava.api.CodeLine;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parent of a constructor or a method.
|
||||||
|
*/
|
||||||
public abstract class CodeContainer {
|
public abstract class CodeContainer {
|
||||||
|
|
||||||
protected final List<CodeLine> code = new LinkedList<>();
|
protected final List<CodeLine> code = new LinkedList<>();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package nl.sander.beejava;
|
package nl.sander.beejava;
|
||||||
|
|
||||||
import nl.sander.beejava.api.BeeClass;
|
import nl.sander.beejava.api.BeeSource;
|
||||||
|
import nl.sander.beejava.classinfo.FieldInfo;
|
||||||
import nl.sander.beejava.constantpool.entry.ClassEntry;
|
import nl.sander.beejava.constantpool.entry.ClassEntry;
|
||||||
import nl.sander.beejava.constantpool.entry.ConstantPoolEntry;
|
import nl.sander.beejava.constantpool.entry.ConstantPoolEntry;
|
||||||
|
|
||||||
|
|
@ -11,12 +12,13 @@ import java.util.Set;
|
||||||
class CompiledClass {
|
class CompiledClass {
|
||||||
private final Set<ConstantPoolEntry> constantTree = new LinkedHashSet<>();
|
private final Set<ConstantPoolEntry> constantTree = new LinkedHashSet<>();
|
||||||
private final Set<ClassEntry> interfaces = new HashSet<>();
|
private final Set<ClassEntry> interfaces = new HashSet<>();
|
||||||
private final BeeClass beeClass;
|
private final Set<FieldInfo> fields = new HashSet<>();
|
||||||
|
private final BeeSource beeSource;
|
||||||
private ClassEntry thisClass;
|
private ClassEntry thisClass;
|
||||||
private ClassEntry superClass;
|
private ClassEntry superClass;
|
||||||
|
|
||||||
CompiledClass(BeeClass beeClass) {
|
CompiledClass(BeeSource beeSource) {
|
||||||
this.beeClass = beeClass;
|
this.beeSource = beeSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getSuperIndex() {
|
int getSuperIndex() {
|
||||||
|
|
@ -49,12 +51,8 @@ class CompiledClass {
|
||||||
interfaces.add(interfaceEntry);
|
interfaces.add(interfaceEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
BeeClass getBeeClass() {
|
BeeSource getSource() {
|
||||||
return beeClass;
|
return beeSource;
|
||||||
}
|
|
||||||
|
|
||||||
ClassEntry getThisClass() {
|
|
||||||
return thisClass;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setThisClass(ClassEntry newThisClass) {
|
public void setThisClass(ClassEntry newThisClass) {
|
||||||
|
|
@ -62,4 +60,12 @@ class CompiledClass {
|
||||||
thisClass = newThisClass;
|
thisClass = newThisClass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addField(FieldInfo fieldInfo) {
|
||||||
|
fields.add(fieldInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<FieldInfo> getFields() {
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
package nl.sander.beejava;
|
package nl.sander.beejava;
|
||||||
|
|
||||||
import nl.sander.beejava.api.BeeClass;
|
import nl.sander.beejava.api.BeeSource;
|
||||||
import nl.sander.beejava.api.CodeLine;
|
import nl.sander.beejava.api.CodeLine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a set of a tree of constant pool entries that refer to each other.
|
* Builds a set of a tree of constant pool entries that refer to each other.
|
||||||
* <p>
|
* <p>
|
||||||
* A client must supply a {@link BeeClass} containing a set of {@link CodeLine}s that is assumed to be correct.
|
* A client must supply a {@link BeeSource} containing a set of {@link CodeLine}s that is assumed to be correct.
|
||||||
* It doesn't check if a valid state is reached.
|
* It doesn't check if a valid state is reached.
|
||||||
*/
|
*/
|
||||||
/* So the name isn't entirely correct. Waiting for inspiration.
|
/* So the name isn't entirely correct. Waiting for inspiration.
|
||||||
|
|
@ -16,36 +16,45 @@ public class Compiler {
|
||||||
private final CompiledClass compiledClass;
|
private final CompiledClass compiledClass;
|
||||||
private final ConstantPoolEntryCreator constantPoolEntryCreator;
|
private final ConstantPoolEntryCreator constantPoolEntryCreator;
|
||||||
|
|
||||||
Compiler(CompiledClass compiledClass) {
|
/**
|
||||||
|
* construct a compiler object.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* At this moment I'm not sure if this class will be able to reused.
|
||||||
|
*/
|
||||||
|
public Compiler(CompiledClass compiledClass) {
|
||||||
this.compiledClass = compiledClass;
|
this.compiledClass = compiledClass;
|
||||||
this.constantPoolEntryCreator = new ConstantPoolEntryCreator(compiledClass);
|
this.constantPoolEntryCreator = new ConstantPoolEntryCreator(compiledClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Set of nested entries that make up a single reference. For instance a class reference whose name is a utf8 reference.
|
* compile a BeeSource object into a CompiledClass object.
|
||||||
* In the constant pool they are consecutive entries, but they are created like nodes in a tree structure that models their relation.
|
|
||||||
*
|
*
|
||||||
* @param beeClass the Class object for which the constant pool needs to be created
|
* @param beeSource the Class object for which the constant pool needs to be created
|
||||||
* @return a Set of constant pool entries
|
* @return a CompiledClass object (that can be turned into bytecode)
|
||||||
*/
|
*/
|
||||||
public static CompiledClass compile(BeeClass beeClass) {
|
public static CompiledClass compile(BeeSource beeSource) {
|
||||||
return new Compiler(new CompiledClass(beeClass)).compile();
|
return new Compiler(new CompiledClass(beeSource)).compile();
|
||||||
}
|
}
|
||||||
|
|
||||||
CompiledClass compile() {
|
/**
|
||||||
compiledClass.getBeeClass().getConstructors().forEach(this::updateConstantPool);
|
* construct a CompiledClass object that contains all information for generating the bytecode
|
||||||
compiledClass.getBeeClass().getMethods().forEach(this::updateConstantPool);
|
*/
|
||||||
|
public CompiledClass compile() {
|
||||||
|
compiledClass.getSource().getConstructors().forEach(this::updateConstantPool);
|
||||||
|
compiledClass.getSource().getMethods().forEach(this::updateConstantPool);
|
||||||
// TODO update constant pool for fields ?
|
// TODO update constant pool for fields ?
|
||||||
// TODO update constant pool for methods
|
|
||||||
|
|
||||||
constantPoolEntryCreator.addThisClass();
|
compiledClass.setThisClass(constantPoolEntryCreator.addThisClass());
|
||||||
constantPoolEntryCreator.addInterfaces();
|
constantPoolEntryCreator.addInterfaces();
|
||||||
constantPoolEntryCreator.addFields();
|
constantPoolEntryCreator.addFields();
|
||||||
|
|
||||||
return compiledClass;
|
return compiledClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* inspect a method or constructor, extract items that need to be added, and add them to the constant pool
|
||||||
|
*/
|
||||||
private void updateConstantPool(CodeContainer codeContainer) {
|
private void updateConstantPool(CodeContainer codeContainer) {
|
||||||
codeContainer.getCode().forEach(this::updateConstantPool);
|
codeContainer.getCode().forEach(this::updateConstantPool);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package nl.sander.beejava;
|
||||||
|
|
||||||
import nl.sander.beejava.api.CodeLine;
|
import nl.sander.beejava.api.CodeLine;
|
||||||
import nl.sander.beejava.api.Ref;
|
import nl.sander.beejava.api.Ref;
|
||||||
|
import nl.sander.beejava.classinfo.FieldInfo;
|
||||||
import nl.sander.beejava.constantpool.entry.*;
|
import nl.sander.beejava.constantpool.entry.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
@ -51,13 +52,12 @@ class ConstantPoolEntryCreator {
|
||||||
private ClassEntry getOrCreateClassEntry(CodeLine codeline) {
|
private ClassEntry getOrCreateClassEntry(CodeLine codeline) {
|
||||||
if (codeline.hasRef()) {
|
if (codeline.hasRef()) {
|
||||||
if (codeline.getRef() == Ref.SUPER) { //this and super are rather special
|
if (codeline.getRef() == Ref.SUPER) { //this and super are rather special
|
||||||
ClassEntry superClass = getClassEntry(compiledClass.getBeeClass().getSuperClass().getName());
|
ClassEntry superClass = getClassEntry(compiledClass.getSource().getSuperClass().getName());
|
||||||
compiledClass.setSuperClass(superClass);
|
compiledClass.setSuperClass(superClass);
|
||||||
return superClass;
|
return superClass;
|
||||||
|
|
||||||
} else if (codeline.getRef() == Ref.THIS) {
|
} else if (codeline.getRef() == Ref.THIS) {
|
||||||
addThisClass();
|
return addThisClass();
|
||||||
return compiledClass.getThisClass();
|
|
||||||
}
|
}
|
||||||
} else if (codeline.hasClassName()) {
|
} else if (codeline.hasClassName()) {
|
||||||
return getClassEntry(codeline.getClassName());
|
return getClassEntry(codeline.getClassName());
|
||||||
|
|
@ -66,24 +66,32 @@ class ConstantPoolEntryCreator {
|
||||||
throw new RuntimeException("shouldn't be here");
|
throw new RuntimeException("shouldn't be here");
|
||||||
}
|
}
|
||||||
|
|
||||||
void addThisClass() {
|
ClassEntry addThisClass() {
|
||||||
ClassEntry classEntry = getClassEntry(compiledClass.getBeeClass().getName());
|
ClassEntry classEntry = getClassEntry(compiledClass.getSource().getName());
|
||||||
compiledClass.addConstantPoolEntry(classEntry);
|
compiledClass.addConstantPoolEntry(classEntry);
|
||||||
compiledClass.setThisClass(classEntry);
|
return classEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassEntry getClassEntry(String externalClassName) {
|
private ClassEntry getClassEntry(String externalClassName) {
|
||||||
return cache(new ClassEntry(cache(new Utf8Entry(internalName(externalClassName)))));
|
return cache(new ClassEntry(cache(new Utf8Entry(internalName(externalClassName)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds interfaces to the constant pool as well as the class.
|
||||||
|
*
|
||||||
|
* interfaces[] in the class file is an array of cp entries
|
||||||
|
*/
|
||||||
public void addInterfaces() {
|
public void addInterfaces() {
|
||||||
compiledClass.getBeeClass().getInterfaces().forEach(interfase -> {
|
compiledClass.getSource().getInterfaces().forEach(interfase -> {
|
||||||
ClassEntry interfaceEntry = cache(new ClassEntry(cache(new Utf8Entry(internalName(interfase.getName())))));
|
ClassEntry interfaceEntry = cache(new ClassEntry(cache(new Utf8Entry(internalName(interfase.getName())))));
|
||||||
compiledClass.addInterface(interfaceEntry);
|
compiledClass.addInterface(interfaceEntry);
|
||||||
compiledClass.addConstantPoolEntry(interfaceEntry);
|
compiledClass.addConstantPoolEntry(interfaceEntry);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a constant is in the codeline, it needs to be added to the constant pool.
|
||||||
|
*/
|
||||||
public ConstantPoolEntry getOrCreatePrimitiveEntry(CodeLine codeline) {
|
public ConstantPoolEntry getOrCreatePrimitiveEntry(CodeLine codeline) {
|
||||||
Object v = codeline.getConstValue();
|
Object v = codeline.getConstValue();
|
||||||
|
|
||||||
|
|
@ -102,8 +110,11 @@ class ConstantPoolEntryCreator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addFields() {
|
public void addFields() {
|
||||||
compiledClass.getBeeClass().getFields().forEach(field -> {
|
compiledClass.getSource().getFields()
|
||||||
// TODO
|
.forEach(f -> {
|
||||||
|
Utf8Entry name = cache(new Utf8Entry(f.getName()));
|
||||||
|
Utf8Entry descriptor = cache(new Utf8Entry(internalName(f.getType().getName())));
|
||||||
|
compiledClass.addField(new FieldInfo(name, descriptor).addAccessFlags(f.getAccessFlags()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,8 +127,7 @@ class ConstantPoolEntryCreator {
|
||||||
// First create an object using the supplier, but if it's found in cache, return the cached entry and discard the first.
|
// First create an object using the supplier, but if it's found in cache, return the cached entry and discard the first.
|
||||||
// Can't check for equality unless you create a potential new entry first
|
// Can't check for equality unless you create a potential new entry first
|
||||||
int hash = newEntry.hashCode();
|
int hash = newEntry.hashCode();
|
||||||
T a = (T) cache.computeIfAbsent(hash, k -> newEntry);
|
return (T) cache.computeIfAbsent(hash, k -> newEntry);
|
||||||
return a;
|
|
||||||
// a hashmap with key hash of value is weird right?
|
// a hashmap with key hash of value is weird right?
|
||||||
// A HashSet is a HashMap with entry: key = value, which would work, but I cannot _get_ anything from a set.
|
// A HashSet is a HashMap with entry: key = value, which would work, but I cannot _get_ anything from a set.
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package nl.sander.beejava.api;
|
package nl.sander.beejava.api;
|
||||||
|
|
||||||
import nl.sander.beejava.CodeContainer;
|
import nl.sander.beejava.CodeContainer;
|
||||||
import nl.sander.beejava.flags.MethodAccessFlag;
|
import nl.sander.beejava.flags.MethodAccessFlags;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
@ -9,10 +9,10 @@ import java.util.*;
|
||||||
* Models a constructor
|
* Models a constructor
|
||||||
*/
|
*/
|
||||||
public class BeeConstructor extends CodeContainer {
|
public class BeeConstructor extends CodeContainer {
|
||||||
private final Set<MethodAccessFlag> accessFlags = new HashSet<>();
|
private final Set<MethodAccessFlags> accessFlags = new HashSet<>();
|
||||||
private final Set<BeeParameter> formalParameters = new HashSet<>();
|
private final Set<BeeParameter> formalParameters = new HashSet<>();
|
||||||
|
|
||||||
private BeeConstructor(Set<MethodAccessFlag> accessFlags,
|
private BeeConstructor(Set<MethodAccessFlags> accessFlags,
|
||||||
List<BeeParameter> formalParameters,
|
List<BeeParameter> formalParameters,
|
||||||
List<CodeLine> code) {
|
List<CodeLine> code) {
|
||||||
this.formalParameters.addAll(formalParameters);
|
this.formalParameters.addAll(formalParameters);
|
||||||
|
|
@ -24,7 +24,7 @@ public class BeeConstructor extends CodeContainer {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<MethodAccessFlag> getAccessFlags() {
|
Set<MethodAccessFlags> getAccessFlags() {
|
||||||
return accessFlags;
|
return accessFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,7 +53,7 @@ public class BeeConstructor extends CodeContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private final Set<MethodAccessFlag> accessFlags = new HashSet<>();
|
private final Set<MethodAccessFlags> accessFlags = new HashSet<>();
|
||||||
private final List<BeeParameter> formalParameters = new LinkedList<>();
|
private final List<BeeParameter> formalParameters = new LinkedList<>();
|
||||||
private final List<CodeLine> code = new LinkedList<>();
|
private final List<CodeLine> code = new LinkedList<>();
|
||||||
|
|
||||||
|
|
@ -66,7 +66,7 @@ public class BeeConstructor extends CodeContainer {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder withAccessFlags(MethodAccessFlag... accessFlags) {
|
public Builder withAccessFlags(MethodAccessFlags... accessFlags) {
|
||||||
this.accessFlags.addAll(Arrays.asList(accessFlags));
|
this.accessFlags.addAll(Arrays.asList(accessFlags));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package nl.sander.beejava.api;
|
package nl.sander.beejava.api;
|
||||||
|
|
||||||
import nl.sander.beejava.flags.FieldAccessFlag;
|
import nl.sander.beejava.flags.FieldAccessFlags;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
@ -9,11 +9,11 @@ import java.util.Set;
|
||||||
|
|
||||||
public class BeeField {
|
public class BeeField {
|
||||||
|
|
||||||
private final Set<FieldAccessFlag> accessFlags = new HashSet<>();
|
private final Set<FieldAccessFlags> accessFlags = new HashSet<>();
|
||||||
private final Class<?> type;
|
private final Class<?> type;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private BeeField(Set<FieldAccessFlag> accessFlags, Class<?> type, String name) {
|
private BeeField(Set<FieldAccessFlags> accessFlags, Class<?> type, String name) {
|
||||||
this.accessFlags.addAll(accessFlags);
|
this.accessFlags.addAll(accessFlags);
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
@ -23,7 +23,7 @@ public class BeeField {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<FieldAccessFlag> getAccessFlags() {
|
public Set<FieldAccessFlags> getAccessFlags() {
|
||||||
return accessFlags;
|
return accessFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ public class BeeField {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private final Set<FieldAccessFlag> accessFlags = new HashSet<>();
|
private final Set<FieldAccessFlags> accessFlags = new HashSet<>();
|
||||||
private Class<?> type;
|
private Class<?> type;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ public class BeeField {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BeeField.Builder withAccessFlags(FieldAccessFlag... accessFlags) {
|
public BeeField.Builder withAccessFlags(FieldAccessFlags... accessFlags) {
|
||||||
this.accessFlags.addAll(Arrays.asList(accessFlags));
|
this.accessFlags.addAll(Arrays.asList(accessFlags));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
package nl.sander.beejava.api;
|
package nl.sander.beejava.api;
|
||||||
|
|
||||||
import nl.sander.beejava.CodeContainer;
|
import nl.sander.beejava.CodeContainer;
|
||||||
import nl.sander.beejava.flags.MethodAccessFlag;
|
import nl.sander.beejava.flags.MethodAccessFlags;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public final class BeeMethod extends CodeContainer {
|
public final class BeeMethod extends CodeContainer {
|
||||||
private final Set<MethodAccessFlag> accessFlags = new HashSet<>();
|
private final Set<MethodAccessFlags> accessFlags = new HashSet<>();
|
||||||
private final Set<BeeParameter> formalParameters = new HashSet<>();
|
private final Set<BeeParameter> formalParameters = new HashSet<>();
|
||||||
private final Class<?> returnType;
|
private final Class<?> returnType;
|
||||||
|
|
||||||
private BeeMethod(Set<MethodAccessFlag> accessFlags,
|
private BeeMethod(Set<MethodAccessFlags> accessFlags,
|
||||||
List<BeeParameter> formalParameters,
|
List<BeeParameter> formalParameters,
|
||||||
Class<?> returnType, List<CodeLine> code) {
|
Class<?> returnType, List<CodeLine> code) {
|
||||||
this.accessFlags.addAll(accessFlags);
|
this.accessFlags.addAll(accessFlags);
|
||||||
|
|
@ -24,7 +24,7 @@ public final class BeeMethod extends CodeContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private final Set<MethodAccessFlag> accessFlags = new HashSet<>();
|
private final Set<MethodAccessFlags> accessFlags = new HashSet<>();
|
||||||
private final List<BeeParameter> formalParameters = new LinkedList<>();
|
private final List<BeeParameter> formalParameters = new LinkedList<>();
|
||||||
private final List<CodeLine> code = new LinkedList<>();
|
private final List<CodeLine> code = new LinkedList<>();
|
||||||
private Class<?> returnType;
|
private Class<?> returnType;
|
||||||
|
|
@ -32,7 +32,7 @@ public final class BeeMethod extends CodeContainer {
|
||||||
private Builder() {
|
private Builder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder withAccessFlags(MethodAccessFlag... accessFlags) {
|
public Builder withAccessFlags(MethodAccessFlags... accessFlags) {
|
||||||
this.accessFlags.addAll(Arrays.asList(accessFlags));
|
this.accessFlags.addAll(Arrays.asList(accessFlags));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
package nl.sander.beejava.api;
|
package nl.sander.beejava.api;
|
||||||
|
|
||||||
import nl.sander.beejava.flags.ClassAccessFlag;
|
import nl.sander.beejava.flags.ClassAccessFlags;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class BeeClass {
|
public class BeeSource {
|
||||||
private final Version classFileVersion;
|
private final Version classFileVersion;
|
||||||
private final BeePackage beePackage;
|
private final BeePackage beePackage;
|
||||||
private final Set<ClassAccessFlag> accessFlags = new HashSet<>();
|
private final Set<ClassAccessFlags> accessFlags = new HashSet<>();
|
||||||
private final String simpleName;
|
private final String simpleName;
|
||||||
private final Class<?> superClass;
|
private final Class<?> superClass;
|
||||||
private final Set<Class<?>> interfaces = new HashSet<>();
|
private final Set<Class<?>> interfaces = new HashSet<>();
|
||||||
|
|
@ -18,8 +17,8 @@ public class BeeClass {
|
||||||
private final Set<BeeConstructor> constructors = new HashSet<>();
|
private final Set<BeeConstructor> constructors = new HashSet<>();
|
||||||
private final Set<BeeMethod> methods = new HashSet<>();
|
private final Set<BeeMethod> methods = new HashSet<>();
|
||||||
|
|
||||||
private BeeClass(Version classFileVersion,
|
private BeeSource(Version classFileVersion,
|
||||||
BeePackage beePackage, Set<ClassAccessFlag> accessFlags, String simpleName, Class<?> superClass,
|
BeePackage beePackage, Set<ClassAccessFlags> accessFlags, String simpleName, Class<?> superClass,
|
||||||
Set<Class<?>> interfaces, Set<BeeField> fields, Set<BeeConstructor> constructors, Set<BeeMethod> methods) {
|
Set<Class<?>> interfaces, Set<BeeField> fields, Set<BeeConstructor> constructors, Set<BeeMethod> methods) {
|
||||||
this.classFileVersion = classFileVersion;
|
this.classFileVersion = classFileVersion;
|
||||||
this.beePackage = beePackage;
|
this.beePackage = beePackage;
|
||||||
|
|
@ -32,7 +31,7 @@ public class BeeClass {
|
||||||
this.methods.addAll(methods);
|
this.methods.addAll(methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BeeClass.Builder builder() {
|
public static BeeSource.Builder builder() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,7 +58,7 @@ public class BeeClass {
|
||||||
return methods;
|
return methods;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<ClassAccessFlag> getAccessFlags() {
|
public Set<ClassAccessFlags> getAccessFlags() {
|
||||||
return accessFlags;
|
return accessFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,7 +82,7 @@ public class BeeClass {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private final Set<ClassAccessFlag> accessFlags = new HashSet<>();
|
private final Set<ClassAccessFlags> accessFlags = new HashSet<>();
|
||||||
private final Set<Class<?>> interfaces = new HashSet<>();
|
private final Set<Class<?>> interfaces = new HashSet<>();
|
||||||
private final Set<BeeField> fields = new HashSet<>();
|
private final Set<BeeField> fields = new HashSet<>();
|
||||||
private Version version;
|
private Version version;
|
||||||
|
|
@ -101,17 +100,17 @@ public class BeeClass {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BeeClass.Builder withPackage(String beePackage) {
|
public BeeSource.Builder withPackage(String beePackage) {
|
||||||
this.beePackage = new BeePackage(beePackage);
|
this.beePackage = new BeePackage(beePackage);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BeeClass.Builder withAccessFlags(ClassAccessFlag... accessFlags) {
|
public BeeSource.Builder withAccessFlags(ClassAccessFlags... accessFlags) {
|
||||||
this.accessFlags.addAll(Arrays.asList(accessFlags));
|
this.accessFlags.addAll(Arrays.asList(accessFlags));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BeeClass.Builder withSimpleName(String simpleName) {
|
public BeeSource.Builder withSimpleName(String simpleName) {
|
||||||
this.simpleName = simpleName;
|
this.simpleName = simpleName;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -141,8 +140,8 @@ public class BeeClass {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BeeClass build() {
|
public BeeSource build() {
|
||||||
return new BeeClass(version, beePackage, accessFlags, simpleName, superClass, interfaces, fields, constructors, methods);
|
return new BeeSource(version, beePackage, accessFlags, simpleName, superClass, interfaces, fields, constructors, methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
11
src/main/java/nl/sander/beejava/classinfo/AttributeInfo.java
Normal file
11
src/main/java/nl/sander/beejava/classinfo/AttributeInfo.java
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
package nl.sander.beejava.classinfo;
|
||||||
|
|
||||||
|
import nl.sander.beejava.constantpool.entry.Utf8Entry;
|
||||||
|
import nl.sander.beejava.util.ByteBuf;
|
||||||
|
|
||||||
|
public abstract class AttributeInfo {
|
||||||
|
private Utf8Entry nameEntry;
|
||||||
|
private int length;
|
||||||
|
|
||||||
|
public abstract void addBytes(ByteBuf buf);
|
||||||
|
}
|
||||||
50
src/main/java/nl/sander/beejava/classinfo/FieldInfo.java
Normal file
50
src/main/java/nl/sander/beejava/classinfo/FieldInfo.java
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
package nl.sander.beejava.classinfo;
|
||||||
|
|
||||||
|
import nl.sander.beejava.constantpool.entry.Utf8Entry;
|
||||||
|
import nl.sander.beejava.flags.AccessFlags;
|
||||||
|
import nl.sander.beejava.flags.FieldAccessFlags;
|
||||||
|
import nl.sander.beejava.util.ByteBuf;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class FieldInfo {
|
||||||
|
private final Set<FieldAccessFlags> accessFlags=new HashSet<>();
|
||||||
|
private final Utf8Entry nameEntry;
|
||||||
|
private final Utf8Entry descriptorEntry;
|
||||||
|
private final Set<AttributeInfo> attributes=new HashSet<>();
|
||||||
|
|
||||||
|
|
||||||
|
public FieldInfo(Utf8Entry nameEntry, Utf8Entry descriptorEntry) {
|
||||||
|
this.nameEntry = nameEntry;
|
||||||
|
this.descriptorEntry = descriptorEntry;
|
||||||
|
}
|
||||||
|
public FieldInfo addAccessFlags(Set<FieldAccessFlags> accessFlags){
|
||||||
|
this.accessFlags.addAll(accessFlags);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<FieldAccessFlags> getAccessFlags() {
|
||||||
|
return accessFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Utf8Entry getNameEntry() {
|
||||||
|
return nameEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Utf8Entry getDescriptorEntry() {
|
||||||
|
return descriptorEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<AttributeInfo> getAttributes() {
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBytes(ByteBuf buf) {
|
||||||
|
buf.addU16(AccessFlags.combine(accessFlags));
|
||||||
|
buf.addU16(nameEntry.getIndex());
|
||||||
|
buf.addU16(descriptorEntry.getIndex());
|
||||||
|
buf.addU16(attributes.size());
|
||||||
|
attributes.forEach(ai -> ai.addBytes(buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,10 +7,12 @@ import java.util.ArrayList;
|
||||||
|
|
||||||
public class ConstantPool extends ArrayList<ConstantPoolEntry>{
|
public class ConstantPool extends ArrayList<ConstantPoolEntry>{
|
||||||
|
|
||||||
public byte[] getBytes() {
|
/**
|
||||||
ByteBuf bytes = new ByteBuf();
|
* Add the bytes for all entries to the given ByteBuf
|
||||||
forEach(entry -> bytes.addU8(entry.getBytes()));
|
* @param buf the buffer that will contain the bytes for the constant pool
|
||||||
return bytes.toBytes();
|
*/
|
||||||
|
public void addTo(ByteBuf buf) {
|
||||||
|
forEach(entry -> buf.addU8(entry.getBytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
package nl.sander.beejava.flags;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
// TODO all access flags can be moved together
|
|
||||||
public interface AccessFlag {
|
|
||||||
|
|
||||||
int getBytecode();
|
|
||||||
|
|
||||||
default int getCombineBytecode(Set<AccessFlag> accessflags) {
|
|
||||||
return accessflags.stream().mapToInt(AccessFlag::getBytecode).sum();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
12
src/main/java/nl/sander/beejava/flags/AccessFlags.java
Normal file
12
src/main/java/nl/sander/beejava/flags/AccessFlags.java
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
package nl.sander.beejava.flags;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public interface AccessFlags {
|
||||||
|
static int combine(Collection<? extends AccessFlags> flags) {
|
||||||
|
return flags.stream().mapToInt(AccessFlags::getBytecode).reduce(0, (result, value) -> result | value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getBytecode();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
package nl.sander.beejava.flags;
|
package nl.sander.beejava.flags;
|
||||||
|
|
||||||
import java.util.Collection;
|
public enum ClassAccessFlags implements AccessFlags {
|
||||||
|
|
||||||
public enum ClassAccessFlag implements AccessFlag {
|
|
||||||
PUBLIC(0x0001), // Declared public; may be accessed from outside its package.
|
PUBLIC(0x0001), // Declared public; may be accessed from outside its package.
|
||||||
FINAL(0x0010), // Declared final; no subclasses allowed.
|
FINAL(0x0010), // Declared final; no subclasses allowed.
|
||||||
SUPER(0x0020), // Treat superclass methods specially when invoked by the invokespecial instruction.
|
SUPER(0x0020), // Treat superclass methods specially when invoked by the invokespecial instruction.
|
||||||
|
|
@ -16,13 +14,11 @@ public enum ClassAccessFlag implements AccessFlag {
|
||||||
|
|
||||||
private final int bytecode;
|
private final int bytecode;
|
||||||
|
|
||||||
ClassAccessFlag(int bytecode) {
|
ClassAccessFlags(int bytecode) {
|
||||||
this.bytecode = bytecode;
|
this.bytecode = bytecode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getSum(Collection<ClassAccessFlag> flags) {
|
|
||||||
return flags.stream().mapToInt(ClassAccessFlag::getBytecode).reduce(0, (result, value) -> result | value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBytecode() {
|
public int getBytecode() {
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
package nl.sander.beejava.flags;
|
package nl.sander.beejava.flags;
|
||||||
|
|
||||||
import nl.sander.beejava.flags.AccessFlag;
|
public enum FieldAccessFlags implements AccessFlags {
|
||||||
|
|
||||||
public enum FieldAccessFlag implements AccessFlag {
|
|
||||||
PUBLIC(0x0001), // Declared public; may be accessed from outside itspackage.
|
PUBLIC(0x0001), // Declared public; may be accessed from outside itspackage.
|
||||||
PRIVATE(0x0002), // Declared private; accessible only within the defining class and other classes belonging to the samenest (§5.4.4).
|
PRIVATE(0x0002), // Declared private; accessible only within the defining class and other classes belonging to the samenest (§5.4.4).
|
||||||
PROTECTED(0x0004), // Declared protected; may be accessed within subclasses.
|
PROTECTED(0x0004), // Declared protected; may be accessed within subclasses.
|
||||||
|
|
@ -15,7 +13,7 @@ public enum FieldAccessFlag implements AccessFlag {
|
||||||
|
|
||||||
private final int bytecode;
|
private final int bytecode;
|
||||||
|
|
||||||
FieldAccessFlag(int bytecode) {
|
FieldAccessFlags(int bytecode) {
|
||||||
this.bytecode = bytecode;
|
this.bytecode = bytecode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
package nl.sander.beejava.flags;
|
package nl.sander.beejava.flags;
|
||||||
|
|
||||||
import nl.sander.beejava.flags.AccessFlag;
|
public enum MethodAccessFlags implements AccessFlags {
|
||||||
|
|
||||||
public enum MethodAccessFlag implements AccessFlag {
|
|
||||||
PUBLIC(0x0001), // Declared public; may be accessed from outside its package.
|
PUBLIC(0x0001), // Declared public; may be accessed from outside its package.
|
||||||
PRIVATE(0x0002), // Declared private; accessible only within the defining class and other classes belonging to the same nest (§5.4.4).
|
PRIVATE(0x0002), // Declared private; accessible only within the defining class and other classes belonging to the same nest (§5.4.4).
|
||||||
PROTECTED(0x0004), // Declared protected; may be accessed within subclasses.
|
PROTECTED(0x0004), // Declared protected; may be accessed within subclasses.
|
||||||
|
|
@ -18,7 +16,7 @@ public enum MethodAccessFlag implements AccessFlag {
|
||||||
|
|
||||||
private final int bytecode;
|
private final int bytecode;
|
||||||
|
|
||||||
MethodAccessFlag(int bytecode) {
|
MethodAccessFlags(int bytecode) {
|
||||||
this.bytecode = bytecode;
|
this.bytecode = bytecode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -21,4 +21,9 @@ public class BytecodeGeneratorTests {
|
||||||
public void testInterface() {
|
public void testInterface() {
|
||||||
BytecodeGenerator.generate(Compiler.compile(TestData.emptyClassWithInterface()));
|
BytecodeGenerator.generate(Compiler.compile(TestData.emptyClassWithInterface()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFields() {
|
||||||
|
BytecodeGenerator.generate(Compiler.compile(TestData.createClassWithField(int.class)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ public class CompilerTests {
|
||||||
@Test // This is not a maintainable test
|
@Test // This is not a maintainable test
|
||||||
public void testMethodRefEntryForSuperConstructor() {
|
public void testMethodRefEntryForSuperConstructor() {
|
||||||
// Arrange
|
// Arrange
|
||||||
BeeClass classWithIntField = TestData.emptyClass();
|
BeeSource classWithIntField = TestData.emptyClass();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
CompiledClass compiledClass = Compiler.compile(classWithIntField);
|
CompiledClass compiledClass = Compiler.compile(classWithIntField);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package nl.sander.beejava;
|
package nl.sander.beejava;
|
||||||
|
|
||||||
import nl.sander.beejava.api.BeeClass;
|
import nl.sander.beejava.api.BeeSource;
|
||||||
import nl.sander.beejava.constantpool.ConstantPool;
|
import nl.sander.beejava.constantpool.ConstantPool;
|
||||||
import nl.sander.beejava.constantpool.entry.ClassEntry;
|
import nl.sander.beejava.constantpool.entry.ClassEntry;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
@ -14,7 +14,7 @@ public class ConstantPoolUniquenessTests {
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
// Arrange
|
// Arrange
|
||||||
BeeClass someClass = TestData.createClassWithTwoReferencesToSomeClass();
|
BeeSource someClass = TestData.createClassWithTwoReferencesToSomeClass();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
CompiledClass compiledClass = Compiler.compile(someClass);
|
CompiledClass compiledClass = Compiler.compile(someClass);
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
package nl.sander.beejava;
|
package nl.sander.beejava;
|
||||||
|
|
||||||
import nl.sander.beejava.api.*;
|
import nl.sander.beejava.api.*;
|
||||||
import nl.sander.beejava.flags.FieldAccessFlag;
|
import nl.sander.beejava.flags.FieldAccessFlags;
|
||||||
import nl.sander.beejava.flags.MethodAccessFlag;
|
import nl.sander.beejava.flags.MethodAccessFlags;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import static nl.sander.beejava.api.CodeLine.line;
|
import static nl.sander.beejava.api.CodeLine.line;
|
||||||
import static nl.sander.beejava.api.Opcode.*;
|
import static nl.sander.beejava.api.Opcode.*;
|
||||||
import static nl.sander.beejava.flags.ClassAccessFlag.PUBLIC;
|
import static nl.sander.beejava.flags.ClassAccessFlags.PUBLIC;
|
||||||
|
|
||||||
public class TestData {
|
public class TestData {
|
||||||
public static BeeClass emptyClass() {
|
public static BeeSource emptyClass() {
|
||||||
return BeeClass.builder()
|
return BeeSource.builder()
|
||||||
.withClassFileVersion(Version.V14)
|
.withClassFileVersion(Version.V14)
|
||||||
.withPackage("nl.sander.beejava.test")
|
.withPackage("nl.sander.beejava.test")
|
||||||
.withAccessFlags(PUBLIC)
|
.withAccessFlags(PUBLIC)
|
||||||
|
|
@ -22,8 +22,8 @@ public class TestData {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BeeClass emptyClassWithInterface() {
|
public static BeeSource emptyClassWithInterface() {
|
||||||
return BeeClass.builder()
|
return BeeSource.builder()
|
||||||
.withClassFileVersion(Version.V14)
|
.withClassFileVersion(Version.V14)
|
||||||
.withPackage("nl.sander.beejava.test")
|
.withPackage("nl.sander.beejava.test")
|
||||||
.withAccessFlags(PUBLIC)
|
.withAccessFlags(PUBLIC)
|
||||||
|
|
@ -34,9 +34,9 @@ public class TestData {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BeeClass createClassWithTwoReferencesToSomeClass() {
|
public static BeeSource createClassWithTwoReferencesToSomeClass() {
|
||||||
BeeMethod print1 = BeeMethod.builder()
|
BeeMethod print1 = BeeMethod.builder()
|
||||||
.withAccessFlags(MethodAccessFlag.PUBLIC)
|
.withAccessFlags(MethodAccessFlags.PUBLIC)
|
||||||
.withCode(
|
.withCode(
|
||||||
line(0, GET, "java.lang.System","out"),
|
line(0, GET, "java.lang.System","out"),
|
||||||
line(1, LD_CONST, "1"),
|
line(1, LD_CONST, "1"),
|
||||||
|
|
@ -45,7 +45,7 @@ public class TestData {
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
BeeMethod print2 = BeeMethod.builder()
|
BeeMethod print2 = BeeMethod.builder()
|
||||||
.withAccessFlags(MethodAccessFlag.PUBLIC)
|
.withAccessFlags(MethodAccessFlags.PUBLIC)
|
||||||
.withCode(
|
.withCode(
|
||||||
line(0, GET, "java.lang.System","out"),
|
line(0, GET, "java.lang.System","out"),
|
||||||
line(1, LD_CONST, "2"),
|
line(1, LD_CONST, "2"),
|
||||||
|
|
@ -53,7 +53,7 @@ public class TestData {
|
||||||
line(3, RETURN))
|
line(3, RETURN))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return BeeClass.builder()
|
return BeeSource.builder()
|
||||||
.withClassFileVersion(Version.V14)
|
.withClassFileVersion(Version.V14)
|
||||||
.withPackage("nl.sander.beejava.test")
|
.withPackage("nl.sander.beejava.test")
|
||||||
.withAccessFlags(PUBLIC)
|
.withAccessFlags(PUBLIC)
|
||||||
|
|
@ -63,9 +63,9 @@ public class TestData {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BeeClass createClassWithField(Class<?> fieldType) {
|
public static BeeSource createClassWithField(Class<?> fieldType) {
|
||||||
BeeField field = BeeField.builder()
|
BeeField field = BeeField.builder()
|
||||||
.withAccessFlags(FieldAccessFlag.PRIVATE)
|
.withAccessFlags(FieldAccessFlags.PRIVATE)
|
||||||
.withType(fieldType)
|
.withType(fieldType)
|
||||||
.withName("field")
|
.withName("field")
|
||||||
.build();
|
.build();
|
||||||
|
|
@ -73,7 +73,7 @@ public class TestData {
|
||||||
BeeParameter parameter = BeeParameter.create(fieldType, "value");
|
BeeParameter parameter = BeeParameter.create(fieldType, "value");
|
||||||
|
|
||||||
BeeConstructor constructor = BeeConstructor.builder()
|
BeeConstructor constructor = BeeConstructor.builder()
|
||||||
.withAccessFlags(MethodAccessFlag.PUBLIC)
|
.withAccessFlags(MethodAccessFlags.PUBLIC)
|
||||||
.withFormalParameters(parameter)
|
.withFormalParameters(parameter)
|
||||||
.withCode(
|
.withCode(
|
||||||
line(0, LD_VAR, Ref.THIS),
|
line(0, LD_VAR, Ref.THIS),
|
||||||
|
|
@ -84,7 +84,7 @@ public class TestData {
|
||||||
line(5, RETURN))
|
line(5, RETURN))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return BeeClass.builder()
|
return BeeSource.builder()
|
||||||
.withClassFileVersion(Version.V14)
|
.withClassFileVersion(Version.V14)
|
||||||
.withPackage("nl.sander.beejava.test")
|
.withPackage("nl.sander.beejava.test")
|
||||||
.withAccessFlags(PUBLIC)
|
.withAccessFlags(PUBLIC)
|
||||||
|
|
@ -97,7 +97,7 @@ public class TestData {
|
||||||
|
|
||||||
private static BeeConstructor createConstructor() {
|
private static BeeConstructor createConstructor() {
|
||||||
return BeeConstructor.builder()
|
return BeeConstructor.builder()
|
||||||
.withAccessFlags(MethodAccessFlag.PUBLIC)
|
.withAccessFlags(MethodAccessFlags.PUBLIC)
|
||||||
.withCode(
|
.withCode(
|
||||||
line(0, LD_VAR, Ref.THIS),
|
line(0, LD_VAR, Ref.THIS),
|
||||||
line(1, INVOKE, Ref.SUPER, "<init>", "()"),
|
line(1, INVOKE, Ref.SUPER, "<init>", "()"),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package nl.sander.beejava;
|
package nl.sander.beejava;
|
||||||
|
|
||||||
import nl.sander.beejava.api.BeeClass;
|
import nl.sander.beejava.api.BeeSource;
|
||||||
import nl.sander.beejava.constantpool.ConstantPool;
|
import nl.sander.beejava.constantpool.ConstantPool;
|
||||||
import nl.sander.beejava.constantpool.entry.NameAndTypeEntry;
|
import nl.sander.beejava.constantpool.entry.NameAndTypeEntry;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
@ -13,10 +13,10 @@ public class TypeMapperTest {
|
||||||
@Test
|
@Test
|
||||||
public void test_int() {
|
public void test_int() {
|
||||||
// Arrange
|
// Arrange
|
||||||
BeeClass beeClass = TestData.createClassWithField(int.class);
|
BeeSource beeSource = TestData.createClassWithField(int.class);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ConstantPool constantPool = createConstantPool(beeClass);
|
ConstantPool constantPool = createConstantPool(beeSource);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
||||||
|
|
@ -26,10 +26,10 @@ public class TypeMapperTest {
|
||||||
@Test
|
@Test
|
||||||
public void test_double() {
|
public void test_double() {
|
||||||
// Arrange
|
// Arrange
|
||||||
BeeClass beeClass = TestData.createClassWithField(double.class);
|
BeeSource beeSource = TestData.createClassWithField(double.class);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ConstantPool constantPool = createConstantPool(beeClass);
|
ConstantPool constantPool = createConstantPool(beeSource);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
||||||
|
|
@ -39,10 +39,10 @@ public class TypeMapperTest {
|
||||||
@Test
|
@Test
|
||||||
public void test_float() {
|
public void test_float() {
|
||||||
// Arrange
|
// Arrange
|
||||||
BeeClass beeClass = TestData.createClassWithField(float.class);
|
BeeSource beeSource = TestData.createClassWithField(float.class);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ConstantPool constantPool = createConstantPool(beeClass);
|
ConstantPool constantPool = createConstantPool(beeSource);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
||||||
|
|
@ -52,10 +52,10 @@ public class TypeMapperTest {
|
||||||
@Test
|
@Test
|
||||||
public void test_byte() {
|
public void test_byte() {
|
||||||
// Arrange
|
// Arrange
|
||||||
BeeClass beeClass = TestData.createClassWithField(byte.class);
|
BeeSource beeSource = TestData.createClassWithField(byte.class);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ConstantPool constantPool = createConstantPool(beeClass);
|
ConstantPool constantPool = createConstantPool(beeSource);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
||||||
|
|
@ -65,10 +65,10 @@ public class TypeMapperTest {
|
||||||
@Test
|
@Test
|
||||||
public void test_short() {
|
public void test_short() {
|
||||||
// Arrange
|
// Arrange
|
||||||
BeeClass beeClass = TestData.createClassWithField(short.class);
|
BeeSource beeSource = TestData.createClassWithField(short.class);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ConstantPool constantPool = createConstantPool(beeClass);
|
ConstantPool constantPool = createConstantPool(beeSource);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
||||||
|
|
@ -78,10 +78,10 @@ public class TypeMapperTest {
|
||||||
@Test
|
@Test
|
||||||
public void test_long() {
|
public void test_long() {
|
||||||
// Arrange
|
// Arrange
|
||||||
BeeClass beeClass = TestData.createClassWithField(long.class);
|
BeeSource beeSource = TestData.createClassWithField(long.class);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ConstantPool constantPool = createConstantPool(beeClass);
|
ConstantPool constantPool = createConstantPool(beeSource);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
||||||
|
|
@ -91,10 +91,10 @@ public class TypeMapperTest {
|
||||||
@Test
|
@Test
|
||||||
public void test_char() {
|
public void test_char() {
|
||||||
// Arrange
|
// Arrange
|
||||||
BeeClass beeClass = TestData.createClassWithField(char.class);
|
BeeSource beeSource = TestData.createClassWithField(char.class);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ConstantPool constantPool = createConstantPool(beeClass);
|
ConstantPool constantPool = createConstantPool(beeSource);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
||||||
|
|
@ -104,10 +104,10 @@ public class TypeMapperTest {
|
||||||
@Test
|
@Test
|
||||||
public void test_boolean() {
|
public void test_boolean() {
|
||||||
// Arrange
|
// Arrange
|
||||||
BeeClass beeClass = TestData.createClassWithField(boolean.class);
|
BeeSource beeSource = TestData.createClassWithField(boolean.class);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ConstantPool constantPool = createConstantPool(beeClass);
|
ConstantPool constantPool = createConstantPool(beeSource);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
||||||
|
|
@ -117,10 +117,10 @@ public class TypeMapperTest {
|
||||||
@Test
|
@Test
|
||||||
public void test_Object() {
|
public void test_Object() {
|
||||||
// Arrange
|
// Arrange
|
||||||
BeeClass beeClass = TestData.createClassWithField(Object.class);
|
BeeSource beeSource = TestData.createClassWithField(Object.class);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ConstantPool constantPool = createConstantPool(beeClass);
|
ConstantPool constantPool = createConstantPool(beeSource);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
||||||
|
|
@ -130,10 +130,10 @@ public class TypeMapperTest {
|
||||||
@Test
|
@Test
|
||||||
public void test_int_array() {
|
public void test_int_array() {
|
||||||
// Arrange
|
// Arrange
|
||||||
BeeClass beeClass = TestData.createClassWithField(int[].class);
|
BeeSource beeSource = TestData.createClassWithField(int[].class);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ConstantPool constantPool = createConstantPool(beeClass);
|
ConstantPool constantPool = createConstantPool(beeSource);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
||||||
|
|
@ -143,18 +143,18 @@ public class TypeMapperTest {
|
||||||
@Test
|
@Test
|
||||||
public void test_Object_array() {
|
public void test_Object_array() {
|
||||||
// Arrange
|
// Arrange
|
||||||
BeeClass beeClass = TestData.createClassWithField(String[].class);
|
BeeSource beeSource = TestData.createClassWithField(String[].class);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ConstantPool constantPool = createConstantPool(beeClass);
|
ConstantPool constantPool = createConstantPool(beeSource);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
NameAndTypeEntry fieldEntry = getFieldNameAndType(constantPool);
|
||||||
assertEquals("[Ljava/lang/String;", fieldEntry.getType());
|
assertEquals("[Ljava/lang/String;", fieldEntry.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConstantPool createConstantPool(BeeClass beeClass) {
|
private ConstantPool createConstantPool(BeeSource beeSource) {
|
||||||
CompiledClass compiledClass = Compiler.compile(beeClass);
|
CompiledClass compiledClass = Compiler.compile(beeSource);
|
||||||
return ConstantPoolCreator.create(compiledClass.getConstantTree());
|
return ConstantPoolCreator.create(compiledClass.getConstantTree());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
package nl.sander.beejava.flags;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
public class ClassAccessFlagTest {
|
|
||||||
@Test
|
|
||||||
public void test_mustOr1Value() {
|
|
||||||
assertEquals(1, ClassAccessFlag.getSum(Collections.singletonList(ClassAccessFlag.PUBLIC)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test_mustOr2Values() {
|
|
||||||
assertEquals(17, ClassAccessFlag.getSum(Arrays.asList(ClassAccessFlag.PUBLIC, ClassAccessFlag.FINAL)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package nl.sander.beejava.flags;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class ClassAccessFlagsTest {
|
||||||
|
@Test
|
||||||
|
public void test_mustOr1Value() {
|
||||||
|
assertEquals(1, AccessFlags.combine(List.of(ClassAccessFlags.PUBLIC)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_mustOr2Values() {
|
||||||
|
assertEquals(17, AccessFlags.combine(List.of(ClassAccessFlags.PUBLIC, ClassAccessFlags.FINAL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue