diff --git a/src/main/java/nl/sander/beejava/apiv2/BeeMethod.java b/src/main/java/nl/sander/beejava/apiv2/BeeMethod.java index 8e55549..d29d62c 100644 --- a/src/main/java/nl/sander/beejava/apiv2/BeeMethod.java +++ b/src/main/java/nl/sander/beejava/apiv2/BeeMethod.java @@ -12,7 +12,7 @@ public final class BeeMethod extends CodeContainer { private final Class returnType; - BeeMethod(String name, Set accessFlags, + public BeeMethod(String name, Set accessFlags, Set formalParameters, Class returnType, List code) { this.name = name; @@ -43,4 +43,19 @@ public final class BeeMethod extends CodeContainer { * -If the name of the method is , 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); + } } diff --git a/src/main/java/nl/sander/beejava/apiv2/CodeContainer.java b/src/main/java/nl/sander/beejava/apiv2/CodeContainer.java index 9da3279..2a3829b 100644 --- a/src/main/java/nl/sander/beejava/apiv2/CodeContainer.java +++ b/src/main/java/nl/sander/beejava/apiv2/CodeContainer.java @@ -3,10 +3,7 @@ package nl.sander.beejava.apiv2; import nl.sander.beejava.TypeMapper; import nl.sander.beejava.flags.MethodAccessFlag; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; /** @@ -54,4 +51,17 @@ public abstract class CodeContainer { } 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); + } } diff --git a/src/main/java/nl/sander/beejava/apiv2/SourceCompiler.java b/src/main/java/nl/sander/beejava/apiv2/SourceCompiler.java index 9c65161..a75ff1f 100644 --- a/src/main/java/nl/sander/beejava/apiv2/SourceCompiler.java +++ b/src/main/java/nl/sander/beejava/apiv2/SourceCompiler.java @@ -16,7 +16,7 @@ import java.util.regex.Pattern; public class SourceCompiler { private final static Pattern firstBlanksplitter = 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 List instructions = new ArrayList<>(); private int currentLine = 0; @@ -34,14 +34,13 @@ public class SourceCompiler { 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); if (currentLine == 0) { parseClassDeclaration(ins, beeSource); } else { parseInstruction(ins, beeSource); } - currentLine += 1; } return beeSource; @@ -61,15 +60,11 @@ public class SourceCompiler { } private BeeMethod parseMethod(String text) { - String[] tokens = split(text, returntypesplitter); + String[] tokens = returntypesplitter.split(text); final String first; final Class returnType; - if (tokens.length > 0) { - try { - returnType = Class.forName(tokens[1].trim()); - } catch (ClassNotFoundException e) { - throw new IllegalArgumentException("Not a valid type: " + tokens[1].trim()); - } + if (tokens.length > 1) { + returnType = getType(tokens[1].trim()); first = tokens[0].trim(); } else { first = text; @@ -89,29 +84,31 @@ public class SourceCompiler { String[] nameParams = split(flagsNameParameters[i], parensplitter); Set parameters = new HashSet<>(); - String methodName = ""; + String methodName=null; if (nameParams.length > 0) { methodName = nameParams[0]; - String params = nameParams[1]; - String[] paramTokens = params.split(","); - for (String paramToken : paramTokens) { - String[] declaration = paramToken.trim().split(" "); - String type = declaration[0]; - String name = declaration[1]; - try { + if (nameParams[1].length() > 0) { + + String params = nameParams[1]; + String[] paramTokens = params.split(","); + for (String paramToken : paramTokens) { + String[] declaration = paramToken.trim().split(" "); + String type = declaration[0]; + String name = declaration[1]; 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; List lines = new ArrayList<>(); Instruction nextInstruction = instructions.get(currentLine); while (nextInstruction instanceof CodeLine) { lines.add((CodeLine) nextInstruction); currentLine += 1; - if (currentLine >= instructions.size()){ + if (currentLine >= instructions.size()) { break; // too tired to think } nextInstruction = instructions.get(currentLine); @@ -121,14 +118,6 @@ public class SourceCompiler { 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) { String[] tokens = split(text, parensplitter); String flag = tokens[0]; @@ -167,7 +156,7 @@ public class SourceCompiler { String type = null; String name = null; for (String token : tokens) { - Optional maybeFlag = FieldAccessFlag.get(token); + Optional maybeFlag = FieldAccessFlag.get(token.toUpperCase()); if (maybeFlag.isPresent()) { flags.add(maybeFlag.get()); } else { @@ -178,11 +167,8 @@ public class SourceCompiler { } } } - try { - return new BeeField(flags, Class.forName(type), name); - } catch (ClassNotFoundException e) { - throw new IllegalArgumentException("field type " + type + " not found"); - } + currentLine += 1; + return new BeeField(flags, getType(type), name); } private void parseClassDeclaration(Instruction firstLine, BeeSource beeSource) { @@ -205,6 +191,7 @@ public class SourceCompiler { } else { throw new IllegalArgumentException("class must start with 'class name(target.jdk.version)'"); } + currentLine += 1; } 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); + } + } } diff --git a/src/test/java/nl/sander/beejava/SourceCompilerTest.java b/src/test/java/nl/sander/beejava/SourceCompilerTest.java index ee440ac..0a90911 100644 --- a/src/test/java/nl/sander/beejava/SourceCompilerTest.java +++ b/src/test/java/nl/sander/beejava/SourceCompilerTest.java @@ -1,14 +1,30 @@ package nl.sander.beejava; -import nl.sander.beejava.apiv2.BeeSource; -import nl.sander.beejava.apiv2.SourceCompiler; +import nl.sander.beejava.apiv2.*; +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 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 { @Test - public void test(){ + public void test() { 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 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()))); } } diff --git a/src/test/java/nl/sander/beejava/TestData2.java b/src/test/java/nl/sander/beejava/TestData2.java index 59de549..2961afd 100644 --- a/src/test/java/nl/sander/beejava/TestData2.java +++ b/src/test/java/nl/sander/beejava/TestData2.java @@ -4,7 +4,7 @@ public class TestData2 { public final static String simpleBean= """ class com.acme.SimpleBean(V15) - field public final int value + field private int value constructor public() INVOKE super() RETURN