diff --git a/src/be/jeffcheasey88/peeratcode/parser/java/Class.java b/src/be/jeffcheasey88/peeratcode/parser/java/Class.java index 157fba3..c25a685 100644 --- a/src/be/jeffcheasey88/peeratcode/parser/java/Class.java +++ b/src/be/jeffcheasey88/peeratcode/parser/java/Class.java @@ -4,7 +4,7 @@ import java.util.List; import be.jeffcheasey88.peeratcode.parser.Token; -public class Class extends JavaElement{ +public class Class extends JavaElement implements FunctionContainer{ private List annotations; @@ -15,6 +15,11 @@ public class Class extends JavaElement{ private List elements; public Class(){} + + @Override + public void addFunction(Function function) { + this.elements.add(function); + } } diff --git a/src/be/jeffcheasey88/peeratcode/parser/java/FunctionContainer.java b/src/be/jeffcheasey88/peeratcode/parser/java/FunctionContainer.java new file mode 100644 index 0000000..2c34755 --- /dev/null +++ b/src/be/jeffcheasey88/peeratcode/parser/java/FunctionContainer.java @@ -0,0 +1,7 @@ +package be.jeffcheasey88.peeratcode.parser.java; + +public interface FunctionContainer{ + + void addFunction(Function function); + +} diff --git a/src/be/jeffcheasey88/peeratcode/parser/java/JavaParser.java b/src/be/jeffcheasey88/peeratcode/parser/java/JavaParser.java index 161d20c..3b30bdb 100644 --- a/src/be/jeffcheasey88/peeratcode/parser/java/JavaParser.java +++ b/src/be/jeffcheasey88/peeratcode/parser/java/JavaParser.java @@ -6,9 +6,11 @@ import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.lang.reflect.Modifier; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.function.BiConsumer; +import java.util.function.BiFunction; import be.jeffcheasey88.peeratcode.parser.Bag; import be.jeffcheasey88.peeratcode.parser.Parser; @@ -616,53 +618,83 @@ public class JavaParser extends Parser { function_container.then(operation); //FUNCTION + BiFunction function_builder = (parent, bag) -> { + buildVariable(bag); + Integer mod = bag.get("mod"); + Function function = new Function(mod == null ? 0 : mod, bag.get("generic"), bag.get("type"), bag.get("name"), bag.get("param"), bag.get("throws")); + if(parent instanceof FunctionContainer) ((FunctionContainer)parent).addFunction(function); + return function; + }; + InitialStateTree function = new InitialStateTree<>(); function.multiple(annotation); - BuilderStateTree function_static = function.then((validator) -> validator.validate((token) -> token.getValue().equals("static")) && validator.validate((token) -> token.getValue().equals("{"))).end((a,b) -> a); + BuilderStateTree function_static = function.then((validator) -> validator.validate((token) -> token.getValue().equals("static")) && validator.validate((token) -> token.getValue().equals("{"))).end((parent, bag) -> { + Function build = new Function(Modifier.STATIC, null, null); + if(parent instanceof FunctionContainer) ((FunctionContainer)parent).addFunction(build); + return build; + }); function_static.multiple(function_container); - function_static.unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))).end((a,b) -> a); - StateTree function_mod = function.then(new RedirectStateTree<>(modifier, (global, local) -> global.set("modifier", local))); - StateTree function_generic = function.then(new RedirectStateTree<>(gen, (global, local) -> global.set("generic", local))); - StateTree function_type = function.then(new RedirectStateTree<>(type, (global, local) -> global.set("type", local))); + function_static.unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))).end(); + StateTree function_mod = function.then(new RedirectStateTree<>(modifier, (global, local) -> { + Integer mod = global.get("mod"); + if(mod == null) global.set("mod", local.get()); + else global.set("mod", mod+local.get()); + })); + StateTree function_generic = function.then(new RedirectStateTree<>(gen, (global, local) -> global.set("generic", local.get()))); + StateTree function_type = function.then(new RedirectStateTree<>(type, (global, local) -> global.set("type", local.get()))); + function_mod.then(function_mod); function_mod.then(function_generic); function_mod.then(function_type); function_generic.then(function_type); StateTree function_name = function.then((validator) -> validator.validate( (token) -> token.getType().equals(TokenType.NAME), - (bag, token) -> System.out.println("declared function "+token.getValue()))); + (bag, token) -> bag.set("name", token))); function_type.then(function_name); StateTree function_begin = function_name.then((validator) -> validator.validate((token) -> token.getValue().equals("("))); StateTree function_end = function_begin.then((validator) -> validator.validate((token) -> token.getValue().equals(")"))); function_end.then((validator) -> validator.validate((token) -> token.getValue().equals("{"))) - .end((a,b) -> a) + .end(function_builder) .multiple(function_container) - .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))).end((a,b) -> a); - function_end.then((validator) -> validator.validate((token) -> token.getValue().equals(";"))).end((a,b) -> a); + .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))).end(); + function_end.then((validator) -> validator.validate((token) -> token.getValue().equals(";"))).end(); function_end.then((validator) -> validator.validate((token) -> token.getValue().equals("default"))) - .then(new RedirectStateTree<>(value_container, (global, local) -> global.set(null))) + .then(new RedirectStateTree<>(value_container, (global, local) -> System.out.println("TODO DEFAULT IN FUNCTION"))) .then((validator) -> validator.validate((token) -> token.getValue().equals(";"))) - .end((a,b) -> a); + .end(function_builder); StateTree function_throws = function_end.then((validator) -> validator.validate((token) -> token.getValue().equals("throws"))) - .then(new RedirectStateTree<>(type, (global, local) -> global.set(null))); - BuilderStateTree function_start_throws = function_throws.then((validator) -> validator.validate((token) -> token.getValue().equals("{"))).end((a,b) -> a); + .then(new RedirectStateTree<>(type, (global, local) -> { + List throwables = global.get("throws"); + if(throwables == null){ + throwables = new ArrayList<>(); + global.set("throws", throwables); + } + throwables.add(local.get()); + })); + BuilderStateTree function_start_throws = function_throws.then((validator) -> validator.validate((token) -> token.getValue().equals("{"))).end(function_builder); function_start_throws.multiple(function_container); - function_start_throws.unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))).end((a,b) -> a); + function_start_throws.unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))).end(); function_throws.then((validator) -> validator.validate((token) -> token.getValue().equals(","))).then(function_throws); - function_throws.then((validator) -> validator.validate((token) -> token.getValue().equals(";"))).end((a,b) -> a); + function_throws.then((validator) -> validator.validate((token) -> token.getValue().equals(";"))).end(function_builder); - StateTree function_arg_mod = function_begin.then((validator) -> validator.validate((token) -> getModifier(token.getValue()) > 0)); - StateTree function_arg_type = function_begin.then(new RedirectStateTree<>(type, (global, local) -> global.set(null))); + StateTree function_arg_mod = function_begin.then((validator) -> validator.validate((token) -> token.getValue().equals("final"), (bag, token) -> bag.set("arg_mod", true))); + StateTree function_arg_type = function_begin.then(new RedirectStateTree<>(type, (global, local) -> global.set("arg_type", local.get()))); function_arg_mod.then(function_arg_type); - StateTree function_arg_name = function_arg_type.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.NAME))); + StateTree function_arg_type_array_begin = function_arg_type.then((validator) -> validator.validate((token) -> token.getValue().equals("["), (bag, token) -> bag.set("arg_type", bag.get("arg_type").concat(token)))); + StateTree function_arg_type_array_end = function_arg_type_array_begin.then((validator) -> validator.validate((token) -> token.getValue().equals("]"), (bag, token) -> bag.set("arg_type", bag.get("arg_type").concat(token)))); + function_arg_type_array_end.then(function_arg_type_array_begin); + StateTree function_arg_name = function_arg_type.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.NAME), (bag, token) -> bag.set("arg_name", token))); + function_arg_type_array_end.then(function_arg_name); function_arg_type.then((validator) -> validator.validate((token) -> token.getValue().equals(".")) && validator.validate((token) -> token.getValue().equals(".")) && - validator.validate((token) -> token.getValue().equals("."))) + validator.validate((token) -> token.getValue().equals("."), (bag, token) -> bag.set("arg_elips", true))) .then(function_arg_name); - StateTree function_arg_split = function_arg_name.then((validator) -> validator.validate((token) -> token.getValue().equals(","))); + StateTree function_arg_split = function_arg_name.then((validator) -> validator.validate((token) -> token.getValue().equals(","), (bag, token) -> { + buildVariable(bag); + })); function_arg_split.then(function_arg_mod); function_arg_split.then(function_arg_type); function_arg_name.then(function_end); @@ -834,6 +866,27 @@ public class JavaParser extends Parser { System.out.println("init"); } + private static void buildVariable(Bag bag){ + if(!bag.has("arg_name")) return; + + List parameters = bag.get("param"); + if(parameters == null){ + parameters = new ArrayList<>(); + bag.set("param", parameters); + } + + Integer mod = bag.get("arg_mod"); + + Variable variable = new Variable(mod == null ? 0 : mod, bag.get("arg_type"), bag.get("arg_name"), bag.get("arg_elips") == Boolean.TRUE); + bag.remove("arg_name"); + bag.remove("arg_mod"); + bag.remove("arg_type"); + bag.remove("arg_name"); + bag.remove("arg_elips"); + + parameters.add(variable); + } + public static int getModifier(String modifier){ switch(modifier){ case "public": return Modifier.PUBLIC; diff --git a/test/be/jeffcheasey88/peeratcode/parser/java/FunctionTests.java b/test/be/jeffcheasey88/peeratcode/parser/java/FunctionTests.java index e148796..841be4b 100644 --- a/test/be/jeffcheasey88/peeratcode/parser/java/FunctionTests.java +++ b/test/be/jeffcheasey88/peeratcode/parser/java/FunctionTests.java @@ -26,6 +26,7 @@ public class FunctionTests { buildVariable(bag); Integer mod = bag.get("mod"); Function function = new Function(mod == null ? 0 : mod, bag.get("generic"), bag.get("type"), bag.get("name"), bag.get("param"), bag.get("throws")); + if(parent instanceof FunctionContainer) ((FunctionContainer)parent).addFunction(function); return function; };