package accrue.analysis.interprocanalysis;

import polyglot.ast.CodeDecl;
import polyglot.ast.ConstructorDecl;
import polyglot.ast.FieldDecl;
import polyglot.ast.Initializer;
import polyglot.ast.MethodDecl;
import polyglot.ast.Node;
import polyglot.ast.NodeFactory;
import polyglot.frontend.Job;
import polyglot.types.SemanticException;
import polyglot.types.TypeSystem;
import polyglot.util.InternalCompilerError;
import polyglot.visit.ErrorHandlingVisitor;
import polyglot.visit.NodeVisitor;

/**
 * Registers all procedures (methods, constructors, initializers) with
 * the InterAnalysisPass.
 */
public class RegisterProceduresVisitor extends ErrorHandlingVisitor {
    protected final Registrar registrar;

    public RegisterProceduresVisitor(Job job, TypeSystem ts, NodeFactory nf,
            Registrar registrar) {
        super(job, ts, nf);
        this.registrar = registrar;
    }

    @Override
    protected NodeVisitor enterCall(Node n) throws SemanticException {
        if (n instanceof MethodDecl) {
            registrar.registerMethod((MethodDecl) n);
            return bypassChildren(n);
        }
        else if (n instanceof ConstructorDecl) {
            registrar.registerConstructor((ConstructorDecl) n);
            return bypassChildren(n);
        }
        else if (n instanceof Initializer) {
            Initializer i = (Initializer) n;
            registrar.registerInitializer(i);
        }
        else if (n instanceof FieldDecl) {
            FieldDecl fd = (FieldDecl) n;
            registrar.registerFieldDecl(fd);
        }
        else if (n instanceof CodeDecl) {
            throw new InternalCompilerError("Unexpected CodeDecl: "
                    + n.getClass().getName());
        }

        return super.enterCall(n);
    }
}
