<commit_before>package polyglot.visit;

import java.util.*;

import polyglot.ast.*;
import polyglot.frontend.Job;
import polyglot.main.Report;
import polyglot.types.SemanticException;
import polyglot.types.TypeSystem;
import polyglot.util.InternalCompilerError;

/**
 * Visitor which checks that all statements must be reachable
 */
public class ReachChecker extends DataFlow
{
    public ReachChecker(Job job, TypeSystem ts, NodeFactory nf) {
	super(job, ts, nf, 
              true /* forward analysis */, 
              true /* perform dataflow on entry to CodeDecls */);
    }

    public Item createInitialItem(FlowGraph graph, Term node) {
        return DataFlowItem.NOT_REACHABLE;
    }

    protected static class DataFlowItem extends Item {
        final boolean reachable;
        final boolean normalReachable;

        protected DataFlowItem(boolean reachable, boolean normalReachable) {
            this.reachable = reachable;
            this.normalReachable = normalReachable;
        }
        
        // terms that are reachable through normal control flow
        public static DataFlowItem REACHABLE = new DataFlowItem(true, true);
        
        // terms that are reachable only through exception control flow, but
        // not by normal control flow. 
        public static DataFlowItem REACHABLE_EX_ONLY = new DataFlowItem(true, false);

        // terms that are not reachable 
        public static DataFlowItem NOT_REACHABLE = new DataFlowItem(false, false);

        public String toString() {
            return (reachable?"":"not ") + "reachable" +
                   (normalReachable?"":" by exceptions only");
        }
        
        public boolean equals(Object o) {
            if (o instanceof DataFlowItem) {
                return this.reachable == ((DataFlowItem)o).reachable &&
                       this.normalReachable == ((DataFlowItem)o).normalReachable;
            }
            return false;
        }
        public int hashCode() {
            return (reachable ? 5423 : 5753) + (normalReachable ? 31 : -2);
        }
    }

    public Map flow(Item in, FlowGraph graph, Term n, Set succEdgeKeys) {
        if (n == graph.entryNode()) {
            return itemToMap(DataFlowItem.REACHABLE, succEdgeKeys);
        }
        else {
            if (in == DataFlowItem.NOT_REACHABLE) {
                return itemToMap(in, succEdgeKeys);
            }
            
            // in is either REACHABLE or REACHABLE_EX_ONLY.
            // return a map where all exception edges are REACHABLE_EX_ONLY,
            // and all non-exception edges are REACHABLE.
            Map m = itemToMap(DataFlowItem.REACHABLE_EX_ONLY, succEdgeKeys);

            if (succEdgeKeys.contains(FlowGraph.EDGE_KEY_OTHER)) {
                m.put(FlowGraph.EDGE_KEY_OTHER, DataFlowItem.REACHABLE);
            }
            if (succEdgeKeys.contains(FlowGraph.EDGE_KEY_TRUE)) {
                m.put(FlowGraph.EDGE_KEY_TRUE, DataFlowItem.REACHABLE);
            }
            if (succEdgeKeys.contains(FlowGraph.EDGE_KEY_FALSE)) {
                m.put(FlowGraph.EDGE_KEY_FALSE, DataFlowItem.REACHABLE);
            }
            
            return m;
        }
    }

    public Item confluence(List inItems, Term node, FlowGraph graph) {
        throw new InternalCompilerError("Should never be called.");<commit_msg>Modified to make this dataflow more "normal": appropriate data items are chosen in "createInitialItem" instead of "flow".<commit_after>package polyglot.visit;

import java.util.*;

import polyglot.ast.*;
import polyglot.frontend.Job;
import polyglot.main.Report;
import polyglot.types.SemanticException;
import polyglot.types.TypeSystem;
import polyglot.util.InternalCompilerError;

/**
 * Visitor which checks that all statements must be reachable
 */
public class ReachChecker extends DataFlow
{
    public ReachChecker(Job job, TypeSystem ts, NodeFactory nf) {
	super(job, ts, nf, 
              true /* forward analysis */, 
              true /* perform dataflow on entry to CodeDecls */);
    }

    protected static class DataFlowItem extends Item {
        final boolean reachable;
        final boolean normalReachable;

        protected DataFlowItem(boolean reachable, boolean normalReachable) {
            this.reachable = reachable;
            this.normalReachable = normalReachable;
        }
        
        // terms that are reachable through normal control flow
        public static DataFlowItem REACHABLE = new DataFlowItem(true, true);
        
        // terms that are reachable only through exception control flow, but
        // not by normal control flow. 
        public static DataFlowItem REACHABLE_EX_ONLY = new DataFlowItem(true, false);

        // terms that are not reachable 
        public static DataFlowItem NOT_REACHABLE = new DataFlowItem(false, false);

        public String toString() {
            return (reachable?"":"not ") + "reachable" +
                   (normalReachable?"":" by exceptions only");
        }
        
        public boolean equals(Object o) {
            if (o instanceof DataFlowItem) {
                return this.reachable == ((DataFlowItem)o).reachable &&
                       this.normalReachable == ((DataFlowItem)o).normalReachable;
            }
            return false;
        }
        public int hashCode() {
            return (reachable ? 5423 : 5753) + (normalReachable ? 31 : -2);
        }
    }

    public Item createInitialItem(FlowGraph graph, Term node) {
        if (node == graph.entryNode()) {
            return DataFlowItem.REACHABLE;
        }
        else {
            return DataFlowItem.NOT_REACHABLE;
        }
    }
    public Map flow(Item in, FlowGraph graph, Term n, Set succEdgeKeys) {
        if (in == DataFlowItem.NOT_REACHABLE) {
            return itemToMap(in, succEdgeKeys);
        }
        
        // in is either REACHABLE or REACHABLE_EX_ONLY.
        // return a map where all exception edges are REACHABLE_EX_ONLY,
        // and all non-exception edges are REACHABLE.
        Map m = itemToMap(DataFlowItem.REACHABLE_EX_ONLY, succEdgeKeys);

        if (succEdgeKeys.contains(FlowGraph.EDGE_KEY_OTHER)) {
            m.put(FlowGraph.EDGE_KEY_OTHER, DataFlowItem.REACHABLE);
        }
        if (succEdgeKeys.contains(FlowGraph.EDGE_KEY_TRUE)) {
            m.put(FlowGraph.EDGE_KEY_TRUE, DataFlowItem.REACHABLE);
        }
        if (succEdgeKeys.contains(FlowGraph.EDGE_KEY_FALSE)) {
            m.put(FlowGraph.EDGE_KEY_FALSE, DataFlowItem.REACHABLE);
        }
        
        return m;
    }

    public Item confluence(List inItems, Term node, FlowGraph graph) {
        throw new InternalCompilerError("Should never be called.");
{'fraction_non_alphanumeric': 0.08351942831621259, 'fraction_numerical': 0.003275271698675004, 'mean_word_length': 2.245410628019324, 'pattern_counts': {'":': 5, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5433498', 'n_tokens_mistral': 1883, 'n_tokens_neox': 1825, 'n_words': 492}