package dev.peerat.parser.java; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; import dev.peerat.parser.Token; import dev.peerat.parser.TokenType; import dev.peerat.parser.StreamableTree; import dev.peerat.parser.java.Annotation.Annotable; import dev.peerat.parser.java.Operation.OperationContainer; import dev.peerat.parser.java.Variable.VariableContainer; import dev.peerat.parser.java.Variable.VariableStreamable; public class Function extends Annotable implements VariableContainer, OperationContainer{ public static interface FunctionContainer{ void addFunction(Function function); } private int mod; private Token generic; private Token type; private Token name; private List parameters; private List throwables; private List elements; public Function(List annotations, int mod, Token type, Token name){ super(annotations); this.mod = mod; this.type = type; this.name = name; this.elements = new ArrayList<>(); } public Function(List annotations, int mod, Token generic, Token type, Token name){ this(annotations, mod, type, name); this.generic = generic; } public Function(List annotations, int mod, Token generic, Token type, Token name, List parameters){ this(annotations, mod, generic, type, name); this.parameters = parameters; } public Function(List annotations, int mod, Token generic, Token type, Token name, List parameters, List throwables){ this(annotations, mod, generic, type, name, parameters); this.throwables = throwables; } @Override public void addVariable(Variable variable) { this.elements.add(variable); } @Override public void addOperation(Operation operation) { this.elements.add(operation); } public int getModifier(){ return this.mod; } public Token getGeneric(){ return this.generic; } public Token getReturnType(){ return this.type; } public Token getName(){ return this.name; } public List getParameters(){ return this.parameters; } public List getThrowables(){ return this.throwables; } public List getElements(){ return this.elements; } @Override public void build(Builder builder) throws Exception{ super.build(builder); String mod = Modifier.toString(this.mod); builder.append(new Token(type.getLineNumber(), type.getCharacterNumber()-(mod.length()+1), mod, TokenType.GROUP)); builder.append(" "); if(generic != null){ builder.append(generic); builder.append(" "); } builder.append(type); builder.append(" "); builder.append(name); builder.append("("); if(parameters != null){ for(Variable param : this.parameters){ param.build(builder); } } builder.append(")"); if(throwables != null){ builder.append("throws"); for(Token token : throwables){ builder.append(token); } } builder.append("{"); if(elements != null){ for(JavaElement content : this.elements){ content.build(builder); } } builder.append("}"); } @Override public E find(java.util.function.Function finder){ E annotation = super.find(finder); if(annotation != null) return annotation; if(parameters != null){ for(Variable param : this.parameters){ if(finder.apply(param)) return (E) param; } } if(elements != null){ for(JavaElement content : this.elements){ if(finder.apply(content)) return (E) content; } } return null; } @Override public void findAll(java.util.function.Function finder, List list){ super.findAll(finder, list); if(parameters != null){ for(Variable param : this.parameters){ if(finder.apply(param)) list.add((E) param); param.findAll(finder, list); } } if(elements != null){ for(JavaElement content : this.elements){ if(finder.apply(content)) list.add((E) content); content.findAll(finder, list); } } } public FunctionStreamable stream(){ return new FunctionStreamable(); } public class FunctionStreamable implements StreamableTree{ public FunctionStreamable(){} public VariableStreamable variableFilter(Predicate filter){ return null; } } }