added testassertions and fixed more stuff
This commit is contained in:
parent
33400c7268
commit
958a5b3fd7
5 changed files with 84 additions and 45 deletions
|
|
@ -12,7 +12,7 @@ public final class BeeMethod extends CodeContainer {
|
||||||
|
|
||||||
private final Class<?> returnType;
|
private final Class<?> returnType;
|
||||||
|
|
||||||
BeeMethod(String name, Set<MethodAccessFlag> accessFlags,
|
public BeeMethod(String name, Set<MethodAccessFlag> accessFlags,
|
||||||
Set<BeeParameter> formalParameters,
|
Set<BeeParameter> formalParameters,
|
||||||
Class<?> returnType, List<CodeLine> code) {
|
Class<?> returnType, List<CodeLine> code) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
@ -43,4 +43,19 @@ public final class BeeMethod extends CodeContainer {
|
||||||
* -If the name of the method is <clinit>, then the descriptor must denote avoid method, and, in a class file whose version number is 51.0 or above,a method that takes no arguments
|
* -If the name of the method is <clinit>, then the descriptor must denote avoid method, and, in a class file whose version number is 51.0 or above,a method that takes no arguments
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
if (!super.equals(o)) return false;
|
||||||
|
BeeMethod beeMethod = (BeeMethod) o;
|
||||||
|
return name.equals(beeMethod.name) &&
|
||||||
|
returnType.equals(beeMethod.returnType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), name, returnType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,7 @@ package nl.sander.beejava.apiv2;
|
||||||
import nl.sander.beejava.TypeMapper;
|
import nl.sander.beejava.TypeMapper;
|
||||||
import nl.sander.beejava.flags.MethodAccessFlag;
|
import nl.sander.beejava.flags.MethodAccessFlag;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.*;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -54,4 +51,17 @@ public abstract class CodeContainer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean isConstructor();
|
public abstract boolean isConstructor();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
CodeContainer that = (CodeContainer) o;
|
||||||
|
return formalParameters.equals(that.formalParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(formalParameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import java.util.regex.Pattern;
|
||||||
public class SourceCompiler {
|
public class SourceCompiler {
|
||||||
private final static Pattern firstBlanksplitter = Pattern.compile("(.+?) (.+)");
|
private final static Pattern firstBlanksplitter = Pattern.compile("(.+?) (.+)");
|
||||||
private final static Pattern parensplitter = Pattern.compile("(.+?)\\((.*?)\\)");
|
private final static Pattern parensplitter = Pattern.compile("(.+?)\\((.*?)\\)");
|
||||||
private final static Pattern returntypesplitter = Pattern.compile("(.+?)->(.*?)");
|
private final static Pattern returntypesplitter = Pattern.compile("->");
|
||||||
private final String sourcecode;
|
private final String sourcecode;
|
||||||
private final List<Instruction> instructions = new ArrayList<>();
|
private final List<Instruction> instructions = new ArrayList<>();
|
||||||
private int currentLine = 0;
|
private int currentLine = 0;
|
||||||
|
|
@ -34,14 +34,13 @@ public class SourceCompiler {
|
||||||
|
|
||||||
BeeSource beeSource = new nl.sander.beejava.apiv2.BeeSource();
|
BeeSource beeSource = new nl.sander.beejava.apiv2.BeeSource();
|
||||||
|
|
||||||
for (currentLine = 0; currentLine < instructions.size(); currentLine++) {
|
for (currentLine = 0; currentLine < instructions.size(); ) {
|
||||||
Instruction ins = instructions.get(currentLine);
|
Instruction ins = instructions.get(currentLine);
|
||||||
if (currentLine == 0) {
|
if (currentLine == 0) {
|
||||||
parseClassDeclaration(ins, beeSource);
|
parseClassDeclaration(ins, beeSource);
|
||||||
} else {
|
} else {
|
||||||
parseInstruction(ins, beeSource);
|
parseInstruction(ins, beeSource);
|
||||||
}
|
}
|
||||||
currentLine += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return beeSource;
|
return beeSource;
|
||||||
|
|
@ -61,15 +60,11 @@ public class SourceCompiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private BeeMethod parseMethod(String text) {
|
private BeeMethod parseMethod(String text) {
|
||||||
String[] tokens = split(text, returntypesplitter);
|
String[] tokens = returntypesplitter.split(text);
|
||||||
final String first;
|
final String first;
|
||||||
final Class<?> returnType;
|
final Class<?> returnType;
|
||||||
if (tokens.length > 0) {
|
if (tokens.length > 1) {
|
||||||
try {
|
returnType = getType(tokens[1].trim());
|
||||||
returnType = Class.forName(tokens[1].trim());
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new IllegalArgumentException("Not a valid type: " + tokens[1].trim());
|
|
||||||
}
|
|
||||||
first = tokens[0].trim();
|
first = tokens[0].trim();
|
||||||
} else {
|
} else {
|
||||||
first = text;
|
first = text;
|
||||||
|
|
@ -89,29 +84,31 @@ public class SourceCompiler {
|
||||||
|
|
||||||
String[] nameParams = split(flagsNameParameters[i], parensplitter);
|
String[] nameParams = split(flagsNameParameters[i], parensplitter);
|
||||||
Set<BeeParameter> parameters = new HashSet<>();
|
Set<BeeParameter> parameters = new HashSet<>();
|
||||||
String methodName = "";
|
String methodName=null;
|
||||||
if (nameParams.length > 0) {
|
if (nameParams.length > 0) {
|
||||||
methodName = nameParams[0];
|
methodName = nameParams[0];
|
||||||
String params = nameParams[1];
|
if (nameParams[1].length() > 0) {
|
||||||
String[] paramTokens = params.split(",");
|
|
||||||
for (String paramToken : paramTokens) {
|
String params = nameParams[1];
|
||||||
String[] declaration = paramToken.trim().split(" ");
|
String[] paramTokens = params.split(",");
|
||||||
String type = declaration[0];
|
for (String paramToken : paramTokens) {
|
||||||
String name = declaration[1];
|
String[] declaration = paramToken.trim().split(" ");
|
||||||
try {
|
String type = declaration[0];
|
||||||
|
String name = declaration[1];
|
||||||
parameters.add(new BeeParameter(getType(type), name));
|
parameters.add(new BeeParameter(getType(type), name));
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new IllegalArgumentException("field type " + type + " not found");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (methodName==null){
|
||||||
|
throw new IllegalArgumentException("method name not found");
|
||||||
|
}
|
||||||
currentLine += 1;
|
currentLine += 1;
|
||||||
List<CodeLine> lines = new ArrayList<>();
|
List<CodeLine> lines = new ArrayList<>();
|
||||||
Instruction nextInstruction = instructions.get(currentLine);
|
Instruction nextInstruction = instructions.get(currentLine);
|
||||||
while (nextInstruction instanceof CodeLine) {
|
while (nextInstruction instanceof CodeLine) {
|
||||||
lines.add((CodeLine) nextInstruction);
|
lines.add((CodeLine) nextInstruction);
|
||||||
currentLine += 1;
|
currentLine += 1;
|
||||||
if (currentLine >= instructions.size()){
|
if (currentLine >= instructions.size()) {
|
||||||
break; // too tired to think
|
break; // too tired to think
|
||||||
}
|
}
|
||||||
nextInstruction = instructions.get(currentLine);
|
nextInstruction = instructions.get(currentLine);
|
||||||
|
|
@ -121,14 +118,6 @@ public class SourceCompiler {
|
||||||
return new BeeMethod(methodName, flags, parameters, returnType, lines);
|
return new BeeMethod(methodName, flags, parameters, returnType, lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Class<?> getType(String type) throws ClassNotFoundException {
|
|
||||||
return switch (type) {
|
|
||||||
case "int" -> int.class;
|
|
||||||
case "double" -> double.class;
|
|
||||||
default -> Class.forName(type);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private BeeConstructor parseConstructor(String text) {
|
private BeeConstructor parseConstructor(String text) {
|
||||||
String[] tokens = split(text, parensplitter);
|
String[] tokens = split(text, parensplitter);
|
||||||
String flag = tokens[0];
|
String flag = tokens[0];
|
||||||
|
|
@ -167,7 +156,7 @@ public class SourceCompiler {
|
||||||
String type = null;
|
String type = null;
|
||||||
String name = null;
|
String name = null;
|
||||||
for (String token : tokens) {
|
for (String token : tokens) {
|
||||||
Optional<FieldAccessFlag> maybeFlag = FieldAccessFlag.get(token);
|
Optional<FieldAccessFlag> maybeFlag = FieldAccessFlag.get(token.toUpperCase());
|
||||||
if (maybeFlag.isPresent()) {
|
if (maybeFlag.isPresent()) {
|
||||||
flags.add(maybeFlag.get());
|
flags.add(maybeFlag.get());
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -178,11 +167,8 @@ public class SourceCompiler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
currentLine += 1;
|
||||||
return new BeeField(flags, Class.forName(type), name);
|
return new BeeField(flags, getType(type), name);
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new IllegalArgumentException("field type " + type + " not found");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseClassDeclaration(Instruction firstLine, BeeSource beeSource) {
|
private void parseClassDeclaration(Instruction firstLine, BeeSource beeSource) {
|
||||||
|
|
@ -205,6 +191,7 @@ public class SourceCompiler {
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("class must start with 'class name(target.jdk.version)'");
|
throw new IllegalArgumentException("class must start with 'class name(target.jdk.version)'");
|
||||||
}
|
}
|
||||||
|
currentLine += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Instruction compileLine(String line) {
|
private Instruction compileLine(String line) {
|
||||||
|
|
@ -245,4 +232,15 @@ public class SourceCompiler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Class<?> getType(String type) {
|
||||||
|
try {
|
||||||
|
return switch (type) {
|
||||||
|
case "int" -> int.class;
|
||||||
|
case "double" -> double.class;
|
||||||
|
default -> Class.forName(type);
|
||||||
|
};
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new IllegalArgumentException("Not a valid type: " + type);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,30 @@
|
||||||
package nl.sander.beejava;
|
package nl.sander.beejava;
|
||||||
|
|
||||||
import nl.sander.beejava.apiv2.BeeSource;
|
import nl.sander.beejava.apiv2.*;
|
||||||
import nl.sander.beejava.apiv2.SourceCompiler;
|
import nl.sander.beejava.flags.AccessFlags;
|
||||||
|
import nl.sander.beejava.flags.ClassAccessFlags;
|
||||||
|
import nl.sander.beejava.flags.FieldAccessFlag;
|
||||||
|
import nl.sander.beejava.flags.MethodAccessFlag;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public class SourceCompilerTest {
|
public class SourceCompilerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test(){
|
public void test() {
|
||||||
BeeSource beeSource = new SourceCompiler(TestData2.simpleBean).doCompile();
|
BeeSource beeSource = new SourceCompiler(TestData2.simpleBean).doCompile();
|
||||||
System.out.println(beeSource);
|
assertEquals("com.acme.SimpleBean", beeSource.getName());
|
||||||
|
assertEquals(ClassAccessFlags.SUPER.getBytecode() | ClassAccessFlags.PUBLIC.getBytecode(), AccessFlags.combine(beeSource.getAccessFlags()));
|
||||||
|
assertTrue(beeSource.getFields().contains(new BeeField(Set.of(FieldAccessFlag.PRIVATE), int.class, "value")));
|
||||||
|
assertEquals(1, beeSource.getConstructors().size());
|
||||||
|
Set<BeeMethod> methods = beeSource.getMethods();
|
||||||
|
assertEquals(2, methods.size());
|
||||||
|
assertTrue(methods.contains(new BeeMethod("getValue", Set.of(MethodAccessFlag.PUBLIC), Set.of(), int.class, List.of())));
|
||||||
|
assertTrue(methods.contains(new BeeMethod("setValue", Set.of(MethodAccessFlag.PUBLIC), Set.of(new BeeParameter(int.class, "newValue")), Void.TYPE, List.of())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ public class TestData2 {
|
||||||
|
|
||||||
public final static String simpleBean= """
|
public final static String simpleBean= """
|
||||||
class com.acme.SimpleBean(V15)
|
class com.acme.SimpleBean(V15)
|
||||||
field public final int value
|
field private int value
|
||||||
constructor public()
|
constructor public()
|
||||||
INVOKE super()
|
INVOKE super()
|
||||||
RETURN
|
RETURN
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue