peer-at-code-backend/src/be/jeffcheasey88/peeratcode/parser/java/Variable.java

210 lines
6 KiB
Java

package be.jeffcheasey88.peeratcode.parser.java;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.BiFunction;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import be.jeffcheasey88.peeratcode.parser.java.CleanerPool.Cleaner;
public class Variable extends JavaElement{
private static Pattern PATTERN = Pattern.compile("^(\\s*)(.*)$");
private int modifier;
private String name;
private String type;
private Variable value; //Change into operation or JavaElement
public Variable(){}
public Variable(int modifier, String type){
this.modifier = modifier;
this.type = type;
}
public int parse(String content, CleanerPool global, CleanerPool local) throws Exception{
CleanerPool generic = new CleanerPool(
new Cleaner("GENERIC_TYPE",'<','>'),
new Cleaner("GENERIC_ARRAY",'[',']'),
new Cleaner("GENERIC_FUNCTION", '{','}'),
new Cleaner("GENERIC_PARENTHESIS",'(',')'));
if(local == null) local = generic;
else local = local.group(generic);
content = local.clean(content);
Matcher matcher = PATTERN.matcher(content);
matcher.matches();
int offset = matcher.group(1).length();
String body = matcher.group(2);
int equals = indexOf(body, "=");
int quote = indexOf(body,",");
int quotes = indexOf(body, ";");
int min = Math.min(quote, quotes);
body = body.substring(0, min);
if(equals < quote && equals < quotes){
assigment(body, local);
}else{
onlyDefine(body, local);
}
return offset+local.unzipOne(body, (s,p) -> (p.equals("^GENERIC_TYPE") || p.equals("^GENERIC_ARRAY")) ? s : null).length();
}
private void assigment(String content, CleanerPool cleaner){
Iterator<String> values = onlyDefine(content, cleaner);
if(!values.hasNext()) return;
values.next();
if(!values.hasNext()) return;
String spacesValue = values.next();
while(values.hasNext()) spacesValue+=" "+values.next();
this.value = new Value(spacesValue);
}
private Iterator<String> onlyDefine(String content, CleanerPool cleaner){
content = generiqueTypes(content, cleaner);
Iterator<String> values = new ArrayIterator<>(content.split("\\s+"));
String value = null;
int modifier;
while(values.hasNext() && (modifier = JavaParser.getModifier(value = values.next())) > 0){
this.modifier+=modifier;
}
if(this.type == null){
this.type = value;
if(values.hasNext()) value = values.next();
}
if(this.name == null){
this.name = value;
}
return values;
}
private static Pattern UNZIP_STICK = Pattern.compile("\\s+(?<e>[<|(|\\[|\"|'])");
private static Pattern UNZIP_MAJ = Pattern.compile(">(?<e>[^>\\d,;(])");
private static Pattern UNZIP_ARRAY = Pattern.compile("](?<e>[^\\[\\d,;])");
private static Pattern UNZIP_EQUALS_LEFT = Pattern.compile("(?<e>[^=\\s])=");
private static Pattern UNZIP_EQUALS_RIGHT = Pattern.compile("=(?<e>[^=\\s])");
private String generiqueTypes(String content, CleanerPool cleaner){
String unzip = cleaner.unzip(content, (value, pattern) -> {
if(pattern.equals("^GENERIC_FUNCTION")) return null;
if(pattern.equals("^GENERIC_PARENTHESIS")) return value.replace("\\s+", " ");
return value.replaceAll("\\s+", "");
});
unzip = UNZIP_STICK.matcher(unzip).replaceAll("${e}");
unzip = UNZIP_MAJ.matcher(unzip).replaceAll("> ${e}");
unzip = UNZIP_ARRAY.matcher(unzip).replaceAll("] ${e}");
unzip = UNZIP_EQUALS_LEFT.matcher(unzip).replaceAll("${e} =");
unzip = UNZIP_EQUALS_RIGHT.matcher(unzip).replaceAll("= ${e}");
return unzip;
}
private int indexOf(String value, String target){
return value.split(target)[0].length();
}
public int getModifier(){
return this.modifier;
}
public String getName(){
return this.name;
}
public String getType(){
return this.type;
}
public Variable getValue(){
return this.value;
}
@Override
public void build(ArrayBuffer<String> buffer, int tab) throws Exception{
super.build(buffer, tab);
buffer.append((s) -> s+=Modifier.toString(modifier)+(modifier > 0 ? " ":"")+type+" "+name+(value == null ? ";":" = "+value+";"));
buffer.add("");
}
@Override
public <E extends JavaElement> E find(java.util.function.Function<JavaElement, Boolean> search, java.util.function.Function<List<JavaElement>, Boolean> deep, List<JavaElement> trace){
if(search.apply(this)) return (E)this;
trace.add(this);
int index = trace.size()-1;
if(!deep.apply(trace)) return null;
//Value of the variable
trace.remove(index);
return null;
}
@Override
public <E extends JavaElement> E find(BiFunction<JavaElement, List<JavaElement>, Boolean> search, List<JavaElement> trace){
trace.add(this);
int index = trace.size()-1;
if(search.apply(this, trace)) return (E)this;
//value
trace.remove(index);
return null;
}
public static class Value extends Variable{
private String value;
public Value(String value){
this.value = value;
}
public String value(){
return this.value;
}
@Override
public String toString(){
return this.value;
}
}
public static class MultipleDeclaratedVariable extends Variable{
private List<String> names;
private List<Variable> values;
public MultipleDeclaratedVariable(int modifier, String type){
super(modifier, type);
this.names = new ArrayList<>();
this.values = new ArrayList<>();
}
public void addVariable(String name, Variable value){
this.names.add(name);
this.values.add(value);
}
@Override
public void build(ArrayBuffer<String> buffer, int tab) throws Exception {
String spacement = "";
for(int i = 0; i < tab; i++) spacement+="\t";
final String sMod = spacement;
String vars = "";
for(int i = 0; i < this.names.size(); i++){
Variable value = this.values.get(i);
vars+=","+this.names.get(i)+((value == null) ? "" : " = "+value);
}
vars = vars.substring(1);
String varMod = vars;
buffer.append((s) -> s+=sMod+Modifier.toString(getModifier())+" "+getType()+" "+varMod+";");
buffer.add("");
}
}
}