package accrue.analysis.ast;

import java.util.List;

import polyglot.ast.Block;
import polyglot.ast.Catch;
import polyglot.ast.Try_c;
import polyglot.util.Position;
import polyglot.util.SerialVersionUID;
import polyglot.visit.CFGBuilder;

public class AccrueTry_c extends Try_c {
    private static final long serialVersionUID = SerialVersionUID.generate();

    public AccrueTry_c(Position pos, Block tryBlock, List<Catch> catchBlocks,
            Block finallyBlock) {
        super(pos, tryBlock, catchBlocks, finallyBlock);
    }

    @Override
    public <T> List<T> acceptCFG(CFGBuilder<?> v, List<T> succs) {
        // Add edges from the try entry to any catch blocks for Error and
        // RuntimeException.
        CFGBuilder<?> v1 = v.push(this, false);
        CFGBuilder<?> v2 = v.push(this, true);

        // We will not add edges from the try entry for Error and RuntimeException, since we want to be as precise as possible.
//        for (Iterator i = ts.uncheckedExceptions().iterator(); i.hasNext(); ) {
//            Type type = (Type) i.next();
//            v1.visitThrow(tryBlock, ENTRY, type);
//        }

        // Handle the normal return case.  The throw case will be handled
        // specially.
        if (finallyBlock != null) {
            v1.visitCFG(tryBlock, finallyBlock, ENTRY);
            v.visitCFG(finallyBlock, this, EXIT);
        }
        else {
            v1.visitCFG(tryBlock, this, EXIT);
        }

        for (Object element : catchBlocks) {
            Catch cb = (Catch) element;
            if (finallyBlock != null) {
                v2.visitCFG(cb, finallyBlock, ENTRY);
            }
            else {
                v2.visitCFG(cb, this, EXIT);
            }
        }

        return succs;
    }
}
