API draft, constant pool creator working in principle. A working test
This commit is contained in:
parent
e9e66f6291
commit
9aad0e55c6
44 changed files with 1545 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
.idea/
|
||||||
|
target/
|
||||||
|
.DS_Store
|
||||||
|
*.iml
|
||||||
54
javap/nl.sander.beejava.testclasses.IntBean_javap.txt
Normal file
54
javap/nl.sander.beejava.testclasses.IntBean_javap.txt
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
Classfile /Users/Shautvast/IdeaProjects/beejava/target/test-classes/nl/sander/beejava/testclasses/IntBean.class
|
||||||
|
Last modified 2 Oct 2020; size 369 bytes
|
||||||
|
SHA-256 checksum ef66d886f52e768d038ec9e87724671c6a748ea0cd62b1b117c5cfb31bcdb153
|
||||||
|
Compiled from "IntBean.java"
|
||||||
|
public class nl.sander.beejava.testclasses.IntBean
|
||||||
|
minor version: 0
|
||||||
|
major version: 58
|
||||||
|
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
|
||||||
|
this_class: #8 // nl/sander/beejava/testclasses/IntBean
|
||||||
|
super_class: #2 // java/lang/Object
|
||||||
|
interfaces: 0, fields: 1, methods: 1, attributes: 1
|
||||||
|
Constant pool:
|
||||||
|
#1 = Methodref #2.#3 // java/lang/Object."<init>":()V
|
||||||
|
#2 = Class #4 // java/lang/Object
|
||||||
|
#3 = NameAndType #5:#6 // "<init>":()V
|
||||||
|
#4 = Utf8 java/lang/Object
|
||||||
|
#5 = Utf8 <init>
|
||||||
|
#6 = Utf8 ()V
|
||||||
|
#7 = Fieldref #8.#9 // nl/sander/beejava/testclasses/IntBean.intField:I
|
||||||
|
#8 = Class #10 // nl/sander/beejava/testclasses/IntBean
|
||||||
|
#9 = NameAndType #11:#12 // intField:I
|
||||||
|
#10 = Utf8 nl/sander/beejava/testclasses/IntBean
|
||||||
|
#11 = Utf8 intField
|
||||||
|
#12 = Utf8 I
|
||||||
|
#13 = Utf8 (I)V
|
||||||
|
#14 = Utf8 Code
|
||||||
|
#15 = Utf8 LineNumberTable
|
||||||
|
#16 = Utf8 LocalVariableTable
|
||||||
|
#17 = Utf8 this
|
||||||
|
#18 = Utf8 Lnl/sander/beejava/testclasses/IntBean;
|
||||||
|
#19 = Utf8 SourceFile
|
||||||
|
#20 = Utf8 IntBean.java
|
||||||
|
{
|
||||||
|
public nl.sander.beejava.testclasses.IntBean(int);
|
||||||
|
descriptor: (I)V
|
||||||
|
flags: (0x0001) ACC_PUBLIC
|
||||||
|
Code:
|
||||||
|
stack=2, locals=2, args_size=2
|
||||||
|
0: aload_0
|
||||||
|
1: invokespecial #1 // Method java/lang/Object."<init>":()V
|
||||||
|
4: aload_0
|
||||||
|
5: iload_1
|
||||||
|
6: putfield #7 // Field intField:I
|
||||||
|
9: return
|
||||||
|
LineNumberTable:
|
||||||
|
line 6: 0
|
||||||
|
line 7: 4
|
||||||
|
line 8: 9
|
||||||
|
LocalVariableTable:
|
||||||
|
Start Length Slot Name Signature
|
||||||
|
0 10 0 this Lnl/sander/beejava/testclasses/IntBean;
|
||||||
|
0 10 1 intField I
|
||||||
|
}
|
||||||
|
SourceFile: "IntBean.java"
|
||||||
50
pom.xml
Normal file
50
pom.xml
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<name>beejava</name>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>14</source>
|
||||||
|
<target>14</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<groupId>nl.sander</groupId>
|
||||||
|
<artifactId>beejava</artifactId>
|
||||||
|
<version>0.1-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>15</maven.compiler.source>
|
||||||
|
<maven.compiler.target>15</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>5.6.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>1.6.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-all</artifactId>
|
||||||
|
<version>1.10.19</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
123
src/main/java/nl/sander/beejava/BeeClass.java
Normal file
123
src/main/java/nl/sander/beejava/BeeClass.java
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
import nl.sander.beejava.flags.ClassAccessFlag;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class BeeClass {
|
||||||
|
private final Version classFileVersion;
|
||||||
|
private final BeePackage beePackage;
|
||||||
|
private final Set<ClassAccessFlag> accessFlags = new HashSet<>();
|
||||||
|
private final String name;
|
||||||
|
private final Class<?> superClass;
|
||||||
|
private final Set<Class<?>> interfaces = new HashSet<>();
|
||||||
|
private final Set<BeeField> fields = new HashSet<>();
|
||||||
|
private final Set<BeeConstructor> constructors = new HashSet<>();
|
||||||
|
|
||||||
|
private BeeClass(Version classFileVersion,
|
||||||
|
BeePackage beePackage, Set<ClassAccessFlag> accessFlags, String name, Class<?> superClass,
|
||||||
|
Set<Class<?>> interfaces, Set<BeeField> fields, Set<BeeConstructor> constructors) {
|
||||||
|
this.classFileVersion = classFileVersion;
|
||||||
|
this.beePackage = beePackage;
|
||||||
|
this.accessFlags.addAll(accessFlags);
|
||||||
|
this.name = name;
|
||||||
|
this.superClass = superClass;
|
||||||
|
this.interfaces.addAll(interfaces);
|
||||||
|
this.fields.addAll(fields);
|
||||||
|
this.constructors.addAll(constructors);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BeeClass.Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Version getClassFileVersion() {
|
||||||
|
return classFileVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeePackage getPackage() {
|
||||||
|
return beePackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<BeeConstructor> getConstructors() {
|
||||||
|
return constructors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<ClassAccessFlag> getAccessFlags() {
|
||||||
|
return accessFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<?> getSuperClass() {
|
||||||
|
return superClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<BeeField> getFields() {
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private Version version;
|
||||||
|
private final Set<ClassAccessFlag> accessFlags = new HashSet<>();
|
||||||
|
private final Set<Class<?>> interfaces = new HashSet<>();
|
||||||
|
private final Set<BeeField> fields = new HashSet<>();
|
||||||
|
private final Set<BeeConstructor> constructors = new HashSet<>();
|
||||||
|
private BeePackage beePackage;
|
||||||
|
private Class<?> superClass = Object.class;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private Builder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withClassFileVersion(Version version){
|
||||||
|
this.version=version;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeeClass.Builder withPackage(String beePackage) {
|
||||||
|
this.beePackage = new BeePackage(beePackage);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeeClass.Builder withAccessFlags(ClassAccessFlag... accessFlags) {
|
||||||
|
this.accessFlags.addAll(Arrays.asList(accessFlags));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeeClass.Builder withName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withSuperClass(Class<?> superClass) {
|
||||||
|
this.superClass = superClass;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withInterfaces(Class<?>... interfaces) {
|
||||||
|
this.interfaces.addAll(Arrays.asList(interfaces));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withFields(BeeField... fields) {
|
||||||
|
this.fields.addAll(Arrays.asList(fields));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withConstructors(BeeConstructor... constructors) {
|
||||||
|
this.constructors.addAll(Arrays.asList(constructors));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeeClass build() {
|
||||||
|
return new BeeClass(version, beePackage, accessFlags, name, superClass, interfaces, fields, constructors);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
85
src/main/java/nl/sander/beejava/BeeConstructor.java
Normal file
85
src/main/java/nl/sander/beejava/BeeConstructor.java
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
import nl.sander.beejava.flags.MethodAccessFlag;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class BeeConstructor implements ContainsCode{
|
||||||
|
private final Set<MethodAccessFlag> accessFlags = new HashSet<>();
|
||||||
|
private final Set<BeeParameter> formalParameters = new HashSet<>();
|
||||||
|
private final List<CodeLine> code = new LinkedList<>();
|
||||||
|
|
||||||
|
private BeeConstructor(Set<MethodAccessFlag> accessFlags,
|
||||||
|
List<BeeParameter> formalParameters,
|
||||||
|
List<CodeLine> code) {
|
||||||
|
this.formalParameters.addAll(formalParameters);
|
||||||
|
this.accessFlags.addAll(accessFlags);
|
||||||
|
this.code.addAll(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<MethodAccessFlag> getAccessFlags() {
|
||||||
|
return accessFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<BeeParameter> getFormalParameters() {
|
||||||
|
return formalParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CodeLine> getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "BeeConstructor{" +
|
||||||
|
"formalParameters=" + formalParameters +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
BeeConstructor that = (BeeConstructor) o;
|
||||||
|
return formalParameters.equals(that.formalParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(formalParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private final Set<MethodAccessFlag> accessFlags = new HashSet<>();
|
||||||
|
private final List<BeeParameter> formalParameters = new LinkedList<>();
|
||||||
|
private final List<CodeLine> code = new LinkedList<>();
|
||||||
|
|
||||||
|
private Builder() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withFormalParameters(BeeParameter... formalParameters) {
|
||||||
|
this.formalParameters.addAll(Arrays.asList(formalParameters));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withAccessFlags(MethodAccessFlag... accessFlags) {
|
||||||
|
this.accessFlags.addAll(Arrays.asList(accessFlags));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder withCode(CodeLine... lines) {
|
||||||
|
this.code.addAll(Arrays.asList(lines));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeeConstructor build() {
|
||||||
|
return new BeeConstructor(accessFlags, formalParameters, code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
79
src/main/java/nl/sander/beejava/BeeField.java
Normal file
79
src/main/java/nl/sander/beejava/BeeField.java
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
import nl.sander.beejava.flags.FieldAccessFlag;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class BeeField {
|
||||||
|
|
||||||
|
private final Set<FieldAccessFlag> accessFlags = new HashSet<>();
|
||||||
|
private final Class<?> type;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private BeeField(Set<FieldAccessFlag> accessFlags, Class<?> type, String name) {
|
||||||
|
this.accessFlags.addAll(accessFlags);
|
||||||
|
this.type = type;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BeeField.Builder builder(){
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<FieldAccessFlag> getAccessFlags() {
|
||||||
|
return accessFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<?> getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
BeeField beeField = (BeeField) o;
|
||||||
|
return name.equals(beeField.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private final Set<FieldAccessFlag> accessFlags = new HashSet<>();
|
||||||
|
private Class<?> type;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private Builder(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeeField.Builder withAccessFlags(FieldAccessFlag... accessFlags) {
|
||||||
|
this.accessFlags.addAll(Arrays.asList(accessFlags));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeeField.Builder withType(Class<?> type) {
|
||||||
|
this.type=type;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeeField.Builder withName(String name) {
|
||||||
|
this.name=name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeeField build() {
|
||||||
|
return new BeeField(accessFlags, type, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/main/java/nl/sander/beejava/BeePackage.java
Normal file
10
src/main/java/nl/sander/beejava/BeePackage.java
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
class BeePackage {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
BeePackage(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/main/java/nl/sander/beejava/BeeParameter.java
Normal file
38
src/main/java/nl/sander/beejava/BeeParameter.java
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class BeeParameter {
|
||||||
|
private final Class<?> type;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private BeeParameter(Class<?> type, String name) {
|
||||||
|
this.type = type;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BeeParameter create(Class<?> type, String name) {
|
||||||
|
return new BeeParameter(type, Objects.requireNonNull(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<?> getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
BeeParameter that = (BeeParameter) o;
|
||||||
|
return name.equals(that.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
107
src/main/java/nl/sander/beejava/CodeLine.java
Normal file
107
src/main/java/nl/sander/beejava/CodeLine.java
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
|
||||||
|
class CodeLine {
|
||||||
|
private final int linenumber;
|
||||||
|
private final Opcode opcode;
|
||||||
|
private Ref ref;
|
||||||
|
private BeeParameter parameter;
|
||||||
|
private String methodName;
|
||||||
|
private String inputSignature;
|
||||||
|
private String outputSignature;
|
||||||
|
private BeeField field;
|
||||||
|
|
||||||
|
CodeLine(int linenumber, Opcode opcode) {
|
||||||
|
this.linenumber = linenumber;
|
||||||
|
this.opcode = opcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CodeLine line(int nr, Opcode opcode, Ref ref) {
|
||||||
|
return new CodeLine(nr, opcode).withRef(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CodeLine line(int nr, Opcode opcode, Ref ref, String methodNameRef, String inputSignature) {
|
||||||
|
return new CodeLine(nr, opcode).withRef(ref).withMethodName(methodNameRef).withInput(inputSignature).withVoidOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CodeLine line(int nr, Opcode opcode, Ref ref, String methodNameRef, String inputSignature, String outputSignature) {
|
||||||
|
return new CodeLine(nr, opcode).withRef(ref).withMethodName(methodNameRef).withInput(inputSignature).withOutput(outputSignature);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CodeLine line(int nr, Opcode opcode) {
|
||||||
|
return new CodeLine(nr, opcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CodeLine line(int nr, Opcode opcode, BeeParameter parameter) {
|
||||||
|
return new CodeLine(nr, opcode).withParameter(parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CodeLine line(int nr, Opcode opcode, BeeField intField) {
|
||||||
|
return new CodeLine(nr, opcode).withRef(Ref.THIS).withField(intField);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CodeLine withRef(Ref ref) {
|
||||||
|
this.ref = ref;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CodeLine withMethodName(String methodName) {
|
||||||
|
this.methodName = methodName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CodeLine withInput(String inputSignature) {
|
||||||
|
this.inputSignature = inputSignature;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CodeLine withVoidOutput() {
|
||||||
|
return withOutput("V");
|
||||||
|
}
|
||||||
|
|
||||||
|
private CodeLine withOutput(String outputSignature) {
|
||||||
|
this.outputSignature = outputSignature;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CodeLine withParameter(BeeParameter parameter) {
|
||||||
|
this.parameter = parameter;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CodeLine withField(BeeField field) {
|
||||||
|
this.field = field;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMethodName() {
|
||||||
|
return methodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasMethod() {
|
||||||
|
return methodName != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getMethodSignature() {
|
||||||
|
return inputSignature + outputSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref getRef() {
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boolean hasField() {
|
||||||
|
return field != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
BeeField getField() {
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
BeeParameter getParameter() {
|
||||||
|
return parameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
38
src/main/java/nl/sander/beejava/Compiler.java
Normal file
38
src/main/java/nl/sander/beejava/Compiler.java
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
import nl.sander.beejava.constantpool.ConstantPool;
|
||||||
|
import nl.sander.beejava.constantpool.entry.ConstantPoolEntry;
|
||||||
|
import nl.sander.beejava.util.ByteBuf;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class Compiler {
|
||||||
|
|
||||||
|
private final BeeClass beeClass; // maybe not a member?
|
||||||
|
private final ConstantTreeCreator constantTreeCreator = new ConstantTreeCreator();
|
||||||
|
private final ConstantPoolCreator constantPoolCreator = new ConstantPoolCreator();
|
||||||
|
|
||||||
|
public Compiler(BeeClass beeClass) {
|
||||||
|
this.beeClass = beeClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] compile(BeeClass beeClass) {
|
||||||
|
Compiler compiler = new Compiler(beeClass);
|
||||||
|
return compiler.doCompile();
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] doCompile() {
|
||||||
|
ByteBuf buf = new ByteBuf();
|
||||||
|
buf.add(0xCA, 0xFE, 0xBA, 0xBE);
|
||||||
|
buf.add(beeClass.getClassFileVersion().getMinor());
|
||||||
|
buf.add(beeClass.getClassFileVersion().getMajor());
|
||||||
|
|
||||||
|
Set<ConstantPoolEntry> constantTree = constantTreeCreator.createConstantTree(beeClass);
|
||||||
|
ConstantPool constantPool = constantPoolCreator.createConstantPool(constantTree);
|
||||||
|
|
||||||
|
buf.add(constantPool.getBytes());
|
||||||
|
return buf.toBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
47
src/main/java/nl/sander/beejava/ConstantPoolCreator.java
Normal file
47
src/main/java/nl/sander/beejava/ConstantPoolCreator.java
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
import nl.sander.beejava.constantpool.ConstantPool;
|
||||||
|
import nl.sander.beejava.constantpool.entry.ConstantPoolEntry;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
public ConstantPool createConstantPool(Set<ConstantPoolEntry> constantTree) {
|
||||||
|
constantPool = new ConstantPool();
|
||||||
|
constantPool.add(null); // dummy element to align it's index with the indexes in the elements themselves
|
||||||
|
index = 0;
|
||||||
|
updateToplevelElements(constantTree);
|
||||||
|
return constantPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateToplevelElements(Set<ConstantPoolEntry> children) {
|
||||||
|
for (ConstantPoolEntry 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) {
|
||||||
|
// first all direct children
|
||||||
|
for (ConstantPoolEntry child : children) {
|
||||||
|
addToPool(child);
|
||||||
|
}
|
||||||
|
// then further lineage
|
||||||
|
for (ConstantPoolEntry child : children) {
|
||||||
|
updateChildElements(child.getChildren());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addToPool(ConstantPoolEntry entry) {
|
||||||
|
index += 1;
|
||||||
|
entry.setIndex(index);
|
||||||
|
constantPool.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
78
src/main/java/nl/sander/beejava/ConstantTreeCreator.java
Normal file
78
src/main/java/nl/sander/beejava/ConstantTreeCreator.java
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
import nl.sander.beejava.constantpool.entry.*;
|
||||||
|
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a set of a tree of constant pool entries that refer to each other.
|
||||||
|
*
|
||||||
|
* A client must supply a {@link BeeClass} containing a set of {@link CodeLine}s that is assumed to be correct.
|
||||||
|
* It doesn't check if a valid state is reached.
|
||||||
|
*/
|
||||||
|
/* So the name isn't entirely correct. Waiting for inspiration.
|
||||||
|
* also TODO make sure entries aren't duplicates
|
||||||
|
*/
|
||||||
|
public class ConstantTreeCreator {
|
||||||
|
private final Set<ConstantPoolEntry> constantTree = new LinkedHashSet<>();
|
||||||
|
private BeeClass beeClass;
|
||||||
|
|
||||||
|
public Set<ConstantPoolEntry> createConstantTree(BeeClass beeClass) {
|
||||||
|
constantTree.clear();
|
||||||
|
this.beeClass = beeClass;
|
||||||
|
beeClass.getConstructors().forEach(this::updateConstantTree);
|
||||||
|
// TODO update constantTree for fields ?
|
||||||
|
// TODO update constantTree for methods
|
||||||
|
return constantTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateConstantTree(ContainsCode codeContainer) {
|
||||||
|
codeContainer.getCode().forEach(this::updateConstantTree);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO construct multi root tree
|
||||||
|
private void updateConstantTree(CodeLine codeline) {
|
||||||
|
if (codeline.hasMethod()){
|
||||||
|
addMethodRef(codeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (codeline.hasField()) {
|
||||||
|
addFieldRef(codeline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMethodRef(CodeLine codeline) {
|
||||||
|
constantTree.add(new MethodRefEntry(createClassName(codeline), createMethodNameAndType(codeline)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFieldRef(CodeLine codeline) {
|
||||||
|
constantTree.add(new FieldRefEntry(createClassName(codeline), createFieldNameAndType(codeline)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private NameAndTypeEntry createMethodNameAndType(CodeLine codeline) {
|
||||||
|
return new NameAndTypeEntry(new Utf8Entry(codeline.getMethodName()), new Utf8Entry(codeline.getMethodSignature()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private NameAndTypeEntry createFieldNameAndType(CodeLine codeline) {
|
||||||
|
return new NameAndTypeEntry(new Utf8Entry(codeline.getField().getName()), new Utf8Entry(TypeMapper.map(codeline.getField().getType())));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClassEntry createClassName(CodeLine codeline) {
|
||||||
|
return new ClassEntry(new Utf8Entry(internalName(getNameOfClass(codeline))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNameOfClass(CodeLine codeline) {
|
||||||
|
if (codeline.getRef() == Ref.SUPER) {
|
||||||
|
return beeClass.getSuperClass().getName();
|
||||||
|
} else if (codeline.getRef() == Ref.THIS) {
|
||||||
|
return beeClass.getPackage() + "." + beeClass.getName();
|
||||||
|
}
|
||||||
|
throw new RuntimeException("shouldn't be here");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String internalName(String name) {
|
||||||
|
return name.replaceAll("\\.", "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
8
src/main/java/nl/sander/beejava/ContainsCode.java
Normal file
8
src/main/java/nl/sander/beejava/ContainsCode.java
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ContainsCode {
|
||||||
|
|
||||||
|
List<CodeLine> getCode();
|
||||||
|
}
|
||||||
69
src/main/java/nl/sander/beejava/Opcode.java
Normal file
69
src/main/java/nl/sander/beejava/Opcode.java
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
public enum Opcode {
|
||||||
|
LOAD("load"),
|
||||||
|
STORE("store"),
|
||||||
|
CONST("const"),
|
||||||
|
NEWARRAY("new"),
|
||||||
|
RETURN("return"),
|
||||||
|
ARRAYLENGTH("length"),
|
||||||
|
THROW("throw"),
|
||||||
|
PUSH("push"),
|
||||||
|
CHECKCAST("checkcast"),
|
||||||
|
ADD("add"),
|
||||||
|
COMPARE("cmp"),
|
||||||
|
DIVIDE("div"),
|
||||||
|
MULTIPLY("mul"),
|
||||||
|
NEGATE("neg"),
|
||||||
|
REMAINDER("rem"),
|
||||||
|
SUBTRACT("sub"),
|
||||||
|
DUPLICATE("dup"),
|
||||||
|
DUPLICATE_DOWN("dup_x1"),
|
||||||
|
DUPLICATE2("dup2"),
|
||||||
|
DUPLICATE2_DOWN("dup2_x1"),
|
||||||
|
GET("get"),
|
||||||
|
GOTO("goto"),
|
||||||
|
GOTO_W("goto_w"),
|
||||||
|
TO_DOUBLE("2d"),
|
||||||
|
TO_INT("2i"),
|
||||||
|
TO_LONG("2l"),
|
||||||
|
TO_BYTE("2b"),
|
||||||
|
TO_CHAR("2c"),
|
||||||
|
TO_FLOAT("2f"),
|
||||||
|
TO_SHORT("2s"),
|
||||||
|
AND("and"),
|
||||||
|
IF_EQUAL("ifeq"),
|
||||||
|
IF_NOT_EQUAL("ifneq"),
|
||||||
|
IF_LESS_THAN("iflt"),
|
||||||
|
IF_GREATER_OR_EQUAL("ifge"),
|
||||||
|
IF_GREATER_THAN("ifgt"),
|
||||||
|
IF_LESS_OR_EQUAL("ifle"),
|
||||||
|
IF_NOT_NULL("ifnotnull"),
|
||||||
|
IF_NULL("ifnull"),
|
||||||
|
INCREMENT("inc"),
|
||||||
|
INSTANCEOF("instanceof"),
|
||||||
|
INVOKE("invoke"),
|
||||||
|
OR("or"),
|
||||||
|
SHIFT_LEFT("shr"),
|
||||||
|
SHIFT_RIGHT("shl"),
|
||||||
|
LOGICAL_SHIFT_RIGHT("ushr"),
|
||||||
|
XOR("xor"),
|
||||||
|
LOOKUPSWITCH("lookupswitch"),
|
||||||
|
MONITORENTER("monitorenter"),
|
||||||
|
MONITOREXIT("monitorexit"),
|
||||||
|
MULTIANEWARRAY("multinewarray"),
|
||||||
|
NEW("new"),
|
||||||
|
NOP("nop"),
|
||||||
|
POP("pop"),
|
||||||
|
POP2("pop2"),
|
||||||
|
PUT("put"),
|
||||||
|
SWAP("swap"),
|
||||||
|
TABLESWITCH("tableswitch"),
|
||||||
|
WIDE("wide");
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
Opcode(String name) {
|
||||||
|
this.name=name;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/main/java/nl/sander/beejava/Output.java
Normal file
22
src/main/java/nl/sander/beejava/Output.java
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only used to contain void return
|
||||||
|
*/
|
||||||
|
public final class Output {
|
||||||
|
|
||||||
|
public static final Output VOID =new Output();
|
||||||
|
|
||||||
|
private Output() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getClass().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return getClass() == obj.getClass();
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/main/java/nl/sander/beejava/Ref.java
Normal file
10
src/main/java/nl/sander/beejava/Ref.java
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used to indicate this, super, or none of those, in which case it's class
|
||||||
|
*/
|
||||||
|
public enum Ref {
|
||||||
|
THIS,
|
||||||
|
SUPER,
|
||||||
|
CLASS
|
||||||
|
}
|
||||||
20
src/main/java/nl/sander/beejava/TypeMapper.java
Normal file
20
src/main/java/nl/sander/beejava/TypeMapper.java
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class TypeMapper {
|
||||||
|
private static final Map<Class<?>, String> MAP = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
MAP.put(int.class, "I");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String map(Class<?> type) {
|
||||||
|
return Optional.ofNullable(MAP.get(type))
|
||||||
|
.orElseThrow(() -> new RuntimeException("Type " + type.getName() + " not found")); //this MUST not happen -> TODO map all types
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
34
src/main/java/nl/sander/beejava/Version.java
Normal file
34
src/main/java/nl/sander/beejava/Version.java
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
public enum Version {
|
||||||
|
V1_0_2(45),
|
||||||
|
V1_1(45),
|
||||||
|
V1_2(46),
|
||||||
|
V1_3(47),
|
||||||
|
V1_4(48),
|
||||||
|
V5_0(49),
|
||||||
|
V6(50),
|
||||||
|
V7(51),
|
||||||
|
V8(52),
|
||||||
|
V9(53),
|
||||||
|
V10(54),
|
||||||
|
V11(55),
|
||||||
|
V12(56),
|
||||||
|
V13(57),
|
||||||
|
V14(58),
|
||||||
|
V15(59);
|
||||||
|
|
||||||
|
private final int major;
|
||||||
|
|
||||||
|
Version(int major) {
|
||||||
|
this.major = major;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMajor() {
|
||||||
|
return major;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinor(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package nl.sander.beejava.constantpool;
|
||||||
|
|
||||||
|
import nl.sander.beejava.constantpool.entry.ConstantPoolEntry;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ConstantPool {
|
||||||
|
private final List<ConstantPoolEntry> entries=new ArrayList<>();
|
||||||
|
|
||||||
|
public int getIndex(ConstantPoolEntry entry){
|
||||||
|
for (int i=0; i<entries.size(); i++){
|
||||||
|
if (entries.get(i)==entry){
|
||||||
|
return i+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(int index, ConstantPoolEntry entry){
|
||||||
|
entries.add(index, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(ConstantPoolEntry entry){
|
||||||
|
entries.add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getBytes() {
|
||||||
|
return new byte[]{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package nl.sander.beejava.constantpool.entry;
|
||||||
|
|
||||||
|
public class ClassEntry extends ConstantPoolEntry {
|
||||||
|
private final Utf8Entry name;
|
||||||
|
|
||||||
|
public ClassEntry(Utf8Entry name) {
|
||||||
|
super(name);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNameIndex() {
|
||||||
|
return name.getIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ClassEntry{" +
|
||||||
|
"nameIndex=" + getNameIndex() +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package nl.sander.beejava.constantpool.entry;
|
||||||
|
|
||||||
|
public class DoubleEntry extends LeafEntry {
|
||||||
|
private final double doubleVal;
|
||||||
|
|
||||||
|
public DoubleEntry(double doubleVal) {
|
||||||
|
this.doubleVal = doubleVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
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() +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package nl.sander.beejava.constantpool.entry;
|
||||||
|
|
||||||
|
public class FloatEntry extends LeafEntry {
|
||||||
|
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.beejava.constantpool.entry;
|
||||||
|
|
||||||
|
public class IntEntry extends LeafEntry {
|
||||||
|
private final int intVal;
|
||||||
|
|
||||||
|
public IntEntry(int integer) {
|
||||||
|
this.intVal = integer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "IntEntry{" +
|
||||||
|
"intVal=" + intVal +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
//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
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package nl.sander.beejava.constantpool.entry;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class LeafEntry extends ConstantPoolEntry {
|
||||||
|
@Override
|
||||||
|
public Set<ConstantPoolEntry> getChildren() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package nl.sander.beejava.constantpool.entry;
|
||||||
|
|
||||||
|
public class LongEntry extends LeafEntry {
|
||||||
|
|
||||||
|
private final long longVal;
|
||||||
|
|
||||||
|
public LongEntry(long longVal) {
|
||||||
|
this.longVal = longVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "LongEntry{" +
|
||||||
|
"longVal=" + longVal +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
//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
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
//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
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package nl.sander.beejava.constantpool.entry;
|
||||||
|
|
||||||
|
public class ModuleEntry extends ConstantPoolEntry {
|
||||||
|
|
||||||
|
private final Utf8Entry nameEntry;
|
||||||
|
|
||||||
|
public ModuleEntry(Utf8Entry nameEntry) {
|
||||||
|
super(nameEntry);
|
||||||
|
this.nameEntry = nameEntry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package nl.sander.beejava.constantpool.entry;
|
||||||
|
|
||||||
|
public class NameAndTypeEntry extends ConstantPoolEntry {
|
||||||
|
private final Utf8Entry name;
|
||||||
|
private final Utf8Entry type;
|
||||||
|
|
||||||
|
public NameAndTypeEntry(Utf8Entry name, Utf8Entry type) {
|
||||||
|
super(name,type);
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getNameIndex() {
|
||||||
|
return name.getIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTypeIndex() {
|
||||||
|
return type.getIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "NameAndTypeEntry{" +
|
||||||
|
"nameIndex=" + getNameIndex() +
|
||||||
|
", typeIndex=" + getTypeIndex() +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package nl.sander.beejava.constantpool.entry;
|
||||||
|
|
||||||
|
public class StringEntry extends ConstantPoolEntry {
|
||||||
|
private final Utf8Entry utf8;
|
||||||
|
|
||||||
|
public StringEntry(Utf8Entry utf8) {
|
||||||
|
this.utf8 = utf8;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUtf8Index() {
|
||||||
|
return utf8.getIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "StringEntry{" +
|
||||||
|
"utf8Index=" + getUtf8Index() +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
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 + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/main/java/nl/sander/beejava/flags/AccessFlag.java
Normal file
12
src/main/java/nl/sander/beejava/flags/AccessFlag.java
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
package nl.sander.beejava.flags;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface AccessFlag {
|
||||||
|
|
||||||
|
int getBytecode();
|
||||||
|
|
||||||
|
default int getCombineBytecode(Set<AccessFlag> accessflags) {
|
||||||
|
return accessflags.stream().mapToInt(AccessFlag::getBytecode).sum();
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/main/java/nl/sander/beejava/flags/ClassAccessFlag.java
Normal file
26
src/main/java/nl/sander/beejava/flags/ClassAccessFlag.java
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
package nl.sander.beejava.flags;
|
||||||
|
|
||||||
|
import nl.sander.beejava.flags.AccessFlag;
|
||||||
|
|
||||||
|
public enum ClassAccessFlag implements AccessFlag {
|
||||||
|
PUBLIC(0x0001), // Declared public; may be accessed from outside its package.
|
||||||
|
FINAL(0x0010), // Declared final; no subclasses allowed.
|
||||||
|
SUPER(0x0020), // Treat superclass methods specially when invoked by the invokespecial instruction.
|
||||||
|
INTERFACE(0x0200), // Is an interface, not a class.
|
||||||
|
ABSTRACT(0x0400), // Declared abstract; must not be instantiated.
|
||||||
|
SYNTHETIC(0x1000), // Declared synthetic; not present in the source code.
|
||||||
|
ANNOTATION(0x2000), // Declared as an annotation type.
|
||||||
|
ENUM(0x4000), // Declared as an enum type.
|
||||||
|
MODULE(0x8000); // Is a module, not a class or interface.
|
||||||
|
|
||||||
|
private final int bytecode;
|
||||||
|
|
||||||
|
ClassAccessFlag(int bytecode) {
|
||||||
|
this.bytecode=bytecode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBytecode() {
|
||||||
|
return bytecode;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/main/java/nl/sander/beejava/flags/FieldAccessFlag.java
Normal file
25
src/main/java/nl/sander/beejava/flags/FieldAccessFlag.java
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
package nl.sander.beejava.flags;
|
||||||
|
|
||||||
|
import nl.sander.beejava.flags.AccessFlag;
|
||||||
|
|
||||||
|
public enum FieldAccessFlag implements AccessFlag {
|
||||||
|
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).
|
||||||
|
PROTECTED(0x0004), // Declared protected; may be accessed within subclasses.
|
||||||
|
STATIC(0x0008), // Declared static.
|
||||||
|
FINAL(0x0010), // Declared final; never directly assigned to afterobject construction (JLS §17.5).
|
||||||
|
VOLATILE(0x0040), // Declared volatile; cannot be cached.
|
||||||
|
ACC_TRANSIENT(0x0080), // Declared transient; not written or read by apersistent object manager.
|
||||||
|
SYNTHETIC(0x1000), // Declared synthetic; not present in the source code.
|
||||||
|
ENUM(0x4000); //Declared as an element of an enum.
|
||||||
|
|
||||||
|
private final int bytecode;
|
||||||
|
|
||||||
|
FieldAccessFlag(int bytecode) {
|
||||||
|
this.bytecode = bytecode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBytecode() {
|
||||||
|
return bytecode;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/main/java/nl/sander/beejava/flags/MethodAccessFlag.java
Normal file
28
src/main/java/nl/sander/beejava/flags/MethodAccessFlag.java
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
package nl.sander.beejava.flags;
|
||||||
|
|
||||||
|
import nl.sander.beejava.flags.AccessFlag;
|
||||||
|
|
||||||
|
public enum MethodAccessFlag implements AccessFlag {
|
||||||
|
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).
|
||||||
|
PROTECTED(0x0004), // Declared protected; may be accessed within subclasses.
|
||||||
|
STATIC(0x0008), // Declared static.
|
||||||
|
FINAL(0x0010), // Declared final; must not be overridden (§5.4.5).
|
||||||
|
SYNCHRONIZED(0x0020), // Declared synchronized; invocation is wrapped by a monitor use.
|
||||||
|
BRIDGE(0x0040), // A bridge method, generated by the compiler.
|
||||||
|
VARARGS(0x0080), //Declared with variable number of arguments.
|
||||||
|
NATIVE(0x0100), //Declared native; implemented in a language other than the Java programming language.
|
||||||
|
ABSTRACT(0x0400), // Declared abstract; no implementation is provided.
|
||||||
|
STRICT(0x0800), // Declared strictfp; floating-point mode is FP-strict.
|
||||||
|
SYNTHETIC(0x1000); // Declared synthetic; not present in the source code.
|
||||||
|
|
||||||
|
private final int bytecode;
|
||||||
|
|
||||||
|
MethodAccessFlag(int bytecode) {
|
||||||
|
this.bytecode = bytecode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBytecode() {
|
||||||
|
return bytecode;
|
||||||
|
}
|
||||||
|
}
|
||||||
86
src/main/java/nl/sander/beejava/util/ByteBuf.java
Normal file
86
src/main/java/nl/sander/beejava/util/ByteBuf.java
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
package nl.sander.beejava.util;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.charset.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* storage like ArrayList, with bytebuffer instead of array
|
||||||
|
*/
|
||||||
|
public class ByteBuf {
|
||||||
|
|
||||||
|
private ByteBuffer data;
|
||||||
|
|
||||||
|
public ByteBuf() {
|
||||||
|
this(64);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuf(final int initialSize) {
|
||||||
|
data = ByteBuffer.allocate(initialSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return toString(StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString(Charset charset) {
|
||||||
|
data.flip();
|
||||||
|
|
||||||
|
CharsetDecoder decoder = charset.newDecoder(); // decode is not threadsafe, might put it in threadlocal
|
||||||
|
// but I don't think this (newDecoder()+config) is expensive
|
||||||
|
|
||||||
|
decoder.onMalformedInput(CodingErrorAction.REPLACE)
|
||||||
|
.onUnmappableCharacter(CodingErrorAction.REPLACE);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return decoder.decode(data).toString();
|
||||||
|
} catch (CharacterCodingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(final byte c) {
|
||||||
|
if (data.remaining() == 0) {
|
||||||
|
enlarge(1);
|
||||||
|
}
|
||||||
|
data.put(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(final byte[] bytes) {
|
||||||
|
if (data.remaining() < bytes.length) {
|
||||||
|
enlarge(bytes.length);
|
||||||
|
}
|
||||||
|
data.put(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(final int... ints) {
|
||||||
|
if (data.remaining() < ints.length) {
|
||||||
|
enlarge(ints.length);
|
||||||
|
}
|
||||||
|
byte[] bytes = new byte[ints.length];
|
||||||
|
for (int i = 0; i < ints.length; i++) {
|
||||||
|
bytes[i] = (byte) (i & 0xFF);
|
||||||
|
}
|
||||||
|
add(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enlarge(final int size) {
|
||||||
|
final int length1 = 2 * data.limit();
|
||||||
|
final int length2 = data.limit() + size;
|
||||||
|
ByteBuffer newData = ByteBuffer.allocate(Math.max(length1, length2));
|
||||||
|
data.flip();
|
||||||
|
newData.put(data);
|
||||||
|
data = newData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int length() {
|
||||||
|
return data.limit() - data.remaining();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] toBytes() {
|
||||||
|
return data.array();
|
||||||
|
}
|
||||||
|
}
|
||||||
114
src/test/java/nl/sander/beejava/ConstantTeeTests.java
Normal file
114
src/test/java/nl/sander/beejava/ConstantTeeTests.java
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
package nl.sander.beejava;
|
||||||
|
|
||||||
|
import nl.sander.beejava.constantpool.entry.*;
|
||||||
|
import nl.sander.beejava.flags.FieldAccessFlag;
|
||||||
|
import nl.sander.beejava.flags.MethodAccessFlag;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static nl.sander.beejava.CodeLine.line;
|
||||||
|
import static nl.sander.beejava.Opcode.*;
|
||||||
|
import static nl.sander.beejava.flags.ClassAccessFlag.PUBLIC;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class ConstantTeeTests {
|
||||||
|
@Test
|
||||||
|
public void testMethodRefEntryForSuperConstructor() {
|
||||||
|
BeeClass classWithIntField = createEmptyClass();
|
||||||
|
Set<ConstantPoolEntry> constantTree = new ConstantTreeCreator().createConstantTree(classWithIntField);
|
||||||
|
assertEquals(1, constantTree.size());
|
||||||
|
ConstantPoolEntry superConstructor = constantTree.iterator().next();
|
||||||
|
|
||||||
|
assertEquals(MethodRefEntry.class, superConstructor.getClass());
|
||||||
|
MethodRefEntry methodRefEntry = (MethodRefEntry) superConstructor;
|
||||||
|
|
||||||
|
Set<ConstantPoolEntry> methodRefEntryChildren = methodRefEntry.getChildren();
|
||||||
|
assertEquals(2, methodRefEntryChildren.size());
|
||||||
|
|
||||||
|
Iterator<ConstantPoolEntry> firstChildren = methodRefEntryChildren.iterator();
|
||||||
|
ConstantPoolEntry child1 = firstChildren.next();
|
||||||
|
assertEquals(ClassEntry.class, child1.getClass());
|
||||||
|
ClassEntry classEntry = (ClassEntry) child1;
|
||||||
|
|
||||||
|
Set<ConstantPoolEntry> classEntryChildren = classEntry.getChildren();
|
||||||
|
assertEquals(1, classEntryChildren.size());
|
||||||
|
ConstantPoolEntry child2 = classEntryChildren.iterator().next();
|
||||||
|
|
||||||
|
assertEquals(Utf8Entry.class, child2.getClass());
|
||||||
|
Utf8Entry className = (Utf8Entry) child2;
|
||||||
|
assertEquals("java/lang/Object", className.getUtf8());
|
||||||
|
|
||||||
|
ConstantPoolEntry child3 = firstChildren.next();
|
||||||
|
assertEquals(NameAndTypeEntry.class, child3.getClass());
|
||||||
|
NameAndTypeEntry nameAndTypeEntry = (NameAndTypeEntry) child3;
|
||||||
|
|
||||||
|
Set<ConstantPoolEntry> nameAndTypeEntryChildren = nameAndTypeEntry.getChildren();
|
||||||
|
assertEquals(2, nameAndTypeEntryChildren.size());
|
||||||
|
Iterator<ConstantPoolEntry> nameAndTypeChildrenIterator = nameAndTypeEntryChildren.iterator();
|
||||||
|
|
||||||
|
ConstantPoolEntry child4 = nameAndTypeChildrenIterator.next();
|
||||||
|
assertEquals(Utf8Entry.class, child4.getClass());
|
||||||
|
Utf8Entry name = (Utf8Entry) child4;
|
||||||
|
assertEquals("<init>", name.getUtf8());
|
||||||
|
|
||||||
|
ConstantPoolEntry child5 = nameAndTypeChildrenIterator.next();
|
||||||
|
assertEquals(Utf8Entry.class, child5.getClass());
|
||||||
|
Utf8Entry type = (Utf8Entry) child5;
|
||||||
|
assertEquals("()V", type.getUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
private BeeClass createEmptyClass() {
|
||||||
|
BeeConstructor constructor = BeeConstructor.builder()
|
||||||
|
.withAccessFlags(MethodAccessFlag.PUBLIC)
|
||||||
|
.withCode(
|
||||||
|
line(0, LOAD, Ref.THIS),
|
||||||
|
line(1, INVOKE, Ref.SUPER, "<init>", "()"),
|
||||||
|
line(5, RETURN))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return BeeClass.builder()
|
||||||
|
.withClassFileVersion(Version.V14)
|
||||||
|
.withPackage("nl.sander.beejava.test")
|
||||||
|
.withAccessFlags(PUBLIC)
|
||||||
|
.withName("EmptyBean")
|
||||||
|
.withSuperClass(Object.class)
|
||||||
|
.withConstructors(constructor)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private BeeClass createClassWithIntField() {
|
||||||
|
BeeField intField = BeeField.builder()
|
||||||
|
.withAccessFlags(FieldAccessFlag.PRIVATE)
|
||||||
|
.withType(int.class)
|
||||||
|
.withName("intField")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
BeeParameter intValueParameter = BeeParameter.create(int.class, "intValue");
|
||||||
|
|
||||||
|
BeeConstructor constructor = BeeConstructor.builder()
|
||||||
|
.withAccessFlags(MethodAccessFlag.PUBLIC)
|
||||||
|
.withFormalParameters(intValueParameter)
|
||||||
|
.withCode(
|
||||||
|
line(0, LOAD, Ref.THIS),
|
||||||
|
line(1, INVOKE, Ref.SUPER, "<init>", "()"),
|
||||||
|
line(2, LOAD, Ref.THIS),
|
||||||
|
line(3, LOAD, intValueParameter),
|
||||||
|
line(4, PUT, intField),
|
||||||
|
line(5, RETURN))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return BeeClass.builder()
|
||||||
|
.withClassFileVersion(Version.V14)
|
||||||
|
.withPackage("nl.sander.beejava.test")
|
||||||
|
.withAccessFlags(PUBLIC)
|
||||||
|
.withName("IntBean")
|
||||||
|
.withSuperClass(Object.class)
|
||||||
|
.withFields(intField)
|
||||||
|
.withConstructors(constructor)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
10
src/test/java/nl/sander/beejava/testclasses/IntBean.java
Normal file
10
src/test/java/nl/sander/beejava/testclasses/IntBean.java
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
package nl.sander.beejava.testclasses;
|
||||||
|
|
||||||
|
public class IntBean {
|
||||||
|
// private int intField;
|
||||||
|
|
||||||
|
// public IntBean(int intField) {
|
||||||
|
// this.intField = intField;
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue