package de.peeeq.wurstscript.validation;

import de.peeeq.wurstscript.ast.*;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 *
 */
public class ValidateClassMemberUsage {
    public static void checkClassMembers(List<CompilationUnit> toCheck) {
        for (CompilationUnit cu : toCheck) {
            for (WPackage p : cu.getPackages()) {
                checkVarUsage(p);
                checkFuncUsage(p);
            }
        }
    }

    private static void checkVarUsage(WPackage p) {
        Set<GlobalVarDef> definedVars = new HashSet<>();

        p.accept(new WPackage.DefaultVisitor() {

            @Override
            public void visit(ClassDef c) {
                super.visit(c);
                definedVars.addAll(c.getVars());
            }

        });

        p.accept(new WPackage.DefaultVisitor() {

            @Override
            public void visit(ExprVarAccess e) {
                super.visit(e);
                NameDef nameDef = e.attrNameDef();
                if (nameDef instanceof GlobalVarDef) {
                    definedVars.remove(nameDef);
                }
            }

            @Override
            public void visit(ExprVarArrayAccess e) {
                super.visit(e);
                NameDef nameDef = e.attrNameDef();
                if (nameDef instanceof GlobalVarDef) {
                    definedVars.remove(nameDef);
                }
            }

        });

        definedVars.forEach(var -> {
            if (var.attrIsPrivate()) {
                var.addWarning("Private variable <" + var.getName() + "> is never read.");
            }
        });

    }

    private static void checkFuncUsage(WPackage p) {
        Set<FuncDef> definedFuncs = new HashSet<>();

        p.accept(new WPackage.DefaultVisitor() {

            @Override
            public void visit(ClassDef c) {
                super.visit(c);
                definedFuncs.addAll(c.getMethods());
            }

        });

        p.accept(new WPackage.DefaultVisitor() {

            @Override
            public void visit(ExprFunctionCall e) {
                super.visit(e);
                definedFuncs.removeIf(funcDef -> funcDef.getName().equals(e.getFuncName()));
            }

            @Override
            public void visit(ExprFuncRef e) {
                super.visit(e);
                definedFuncs.removeIf(funcDef -> funcDef.getName().equals(e.getFuncName()));
            }

        });

        definedFuncs.forEach(funcDef -> {
            if (funcDef.attrIsPrivate()) {
                funcDef.addWarning("Private function <" + funcDef.getName() + "> is never used.");
            }
        });

    }
}

@@ -527,22 +527,16 @@
     Set%3C
-Global
 VarDef%3E 
@@ -558,32 +558,32 @@
 ew HashSet%3C%3E();%0A
+
 %0A        p.accep
@@ -1027,38 +1027,32 @@
 eDef instanceof 
-Global
 VarDef) %7B%0A      
@@ -1329,14 +1329,1176 @@
 eof 
-Global
+VarDef) %7B%0A                    definedVars.remove(nameDef);%0A                %7D%0A            %7D%0A%0A            @Override%0A            public void visit(ExprMemberVarDot e) %7B%0A                super.visit(e);%0A                NameDef nameDef = e.attrNameDef();%0A                if (nameDef instanceof VarDef) %7B%0A                    definedVars.remove(nameDef);%0A                %7D%0A            %7D%0A%0A            @Override%0A            public void visit(ExprMemberVarDotDot e) %7B%0A                super.visit(e);%0A                NameDef nameDef = e.attrNameDef();%0A                if (nameDef instanceof VarDef) %7B%0A                    definedVars.remove(nameDef);%0A                %7D%0A            %7D%0A%0A            @Override%0A            public void visit(ExprMemberArrayVarDot e) %7B%0A                super.visit(e);%0A                NameDef nameDef = e.attrNameDef();%0A                if (nameDef instanceof VarDef) %7B%0A                    definedVars.remove(nameDef);%0A                %7D%0A            %7D%0A%0A            @Override%0A            public void visit(ExprMemberArrayVarDotDot e) %7B%0A                super.visit(e);%0A                NameDef nameDef = e.attrNameDef();%0A                if (nameDef instanceof 
 VarD

fix var usage detection