package accrue.jl5.pointer;

import polyglot.ast.ClassBody;
import polyglot.ast.ClassMember;
import polyglot.ast.Node;
import polyglot.ast.NodeFactory;
import polyglot.ext.jl5.ast.EnumConstantDecl;
import polyglot.frontend.Job;
import polyglot.types.SemanticException;
import polyglot.types.TypeSystem;
import polyglot.visit.NodeVisitor;
import accrue.analysis.pointer.PointerAnalysisPass;
import accrue.analysis.pointer.RegisterPointerStmtsVisitor;
import accrue.analysis.pointer.StmtRegistrar.CodeInfo;

/**
 * Registers all procedures (methods, constructors, initializers, enum constant decls) with
 * the InterAnalysisPass.
 */
public class JL5RegisterPointerStmtsVisitor extends RegisterPointerStmtsVisitor {

    public JL5RegisterPointerStmtsVisitor(Job job, TypeSystem ts, NodeFactory nf) {
        super(job, ts, nf);
    }

    @Override
    protected NodeVisitor enterCall(Node parent, Node n)
            throws SemanticException {
        JL5StmtRegistrar registrar =
                (JL5StmtRegistrar) PointerAnalysisPass.singleton(job().extensionInfo())
                                                      .registrar();

        // register EnumConstantDecls on entry to class body
        if (n instanceof ClassBody) {
            ClassBody cb = (ClassBody) n;
            for (ClassMember m : cb.members()) {
                if (m instanceof EnumConstantDecl) {
                    registrar.recordEnumConstantDecl((EnumConstantDecl) m);
                }
            }
        }

        if (n instanceof EnumConstantDecl) {
            EnumConstantDecl ecd = (EnumConstantDecl) n;

            CodeInfo codeInfo = registrar.getCodeInfo(ecd);
            return this.codeInfo(codeInfo).visitChildren();
        }

        return super.enterCall(parent, n);
    }
}
