package sugarVisitors;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import ast.ErrorMessage;
import ast.Expression;
import ast.Expression.ClassB;
import ast.Expression.ClassB.Member;
//TODO: also check no varDeclaredTwice over desugared terms!
public class CheckNoVarDeclaredTwice{
public static boolean of(Expression e){
of(e,Collections.emptyList());
return true;
}
public static void of(Expression e,List<String>names){
Local cdv=new Local();
cdv.xs.addAll(names);
cdv.xs.add("this");
e.accept(cdv);
}
private static class Local extends CloneVisitor {
HashSet<String> xs=new HashSet<String>();
@Override
protected <T extends Expression>T lift(T e){
try{ return super.lift(e); }
catch(ErrorMessage.VariableDeclaredMultipleTimes err){
if(e instanceof ast.Ast.HasPos){
throw err.withPos(((ast.Ast.HasPos)e).getP());
} else throw err;
}
}
//Note: this also work for with is and es!
@Override
protected ast.Ast.VarDecXE liftVarDecXE(ast.Ast.VarDecXE d) {
if(xs.contains(d.getX())){
throw new ErrorMessage.VariableDeclaredMultipleTimes(d.getX(),null);
}
assert d.getX().length()>0;
xs.add(d.getX());
try{return super.liftVarDecXE(d);}
finally{xs.remove(d.getX());}
}
@Override
protected Expression.Catch liftK(Expression.Catch k){
if(xs.contains(k.getX())){
throw new ErrorMessage.VariableDeclaredMultipleTimes(k.getX(),null);
}
if(k.getX().length()>0){xs.add(k.getX());}
try{return super.liftK(k);}
finally{xs.remove(k.getX());}
}
public Expression visit(ClassB s) {
for(Member m:s.getMs()){
m.match(
nc->{CheckNoVarDeclaredTwice.of(nc.getInner(),Collections.emptyList());return null;},
mi->{CheckNoVarDeclaredTwice.of(mi.getInner(),mi.getS().getNames());return null;},
mt->{if(mt.getInner().isPresent()){CheckNoVarDeclaredTwice.of(mt.getInner().get(),mt.getMs().getNames());};return null;}
);
}
return s;
}
}
}