1 package polyglot.visit; 2 3 import java.util.*; 4 5 import polyglot.ast.*; 6 import polyglot.frontend.Job; 7 import polyglot.types.SemanticException; 8 import polyglot.types.TypeSystem; 9 10 14 public class ExitChecker extends DataFlow 15 { 16 protected CodeDecl code; 17 18 public ExitChecker(Job job, TypeSystem ts, NodeFactory nf) { 19 super(job, ts, nf, false ); 20 } 21 22 protected FlowGraph initGraph(CodeDecl code, Term root) { 23 boolean returnsValue; 24 25 this.code = code; 26 27 if (code instanceof MethodDecl) { 28 MethodDecl d = (MethodDecl) code; 29 if (! d.methodInstance().returnType().isVoid()) { 30 return super.initGraph(code, root); 31 } 32 } 33 34 return null; 35 } 36 37 public Item createInitialItem(FlowGraph graph, Term node) { 38 return DataFlowItem.EXITS; 39 } 40 41 protected static class DataFlowItem extends Item { 42 final boolean exits; 44 protected DataFlowItem(boolean exits) { 45 this.exits = exits; 46 } 47 48 public static final DataFlowItem EXITS = new DataFlowItem(true); 49 public static final DataFlowItem DOES_NOT_EXIT = new DataFlowItem(false); 50 51 public String toString() { 52 return "exits=" + exits; 53 } 54 public boolean equals(Object o) { 55 if (o instanceof DataFlowItem) { 56 return this.exits == ((DataFlowItem)o).exits; 57 } 58 return false; 59 } 60 public int hashCode() { 61 return (exits ? 5235 : 8673); 62 } 63 64 } 65 66 public Map flow(Item in, FlowGraph graph, Term n, Set succEdgeKeys) { 67 if (n instanceof Return) { 73 return itemToMap(DataFlowItem.EXITS, succEdgeKeys); 74 } 75 76 if (n == graph.exitNode()) { 77 Map m = itemToMap(DataFlowItem.EXITS, succEdgeKeys); 81 if (succEdgeKeys.contains(FlowGraph.EDGE_KEY_OTHER)) { 82 m.put(FlowGraph.EDGE_KEY_OTHER, DataFlowItem.DOES_NOT_EXIT); 83 } 84 if (succEdgeKeys.contains(FlowGraph.EDGE_KEY_TRUE)) { 85 m.put(FlowGraph.EDGE_KEY_TRUE, DataFlowItem.DOES_NOT_EXIT); 86 } 87 if (succEdgeKeys.contains(FlowGraph.EDGE_KEY_FALSE)) { 88 m.put(FlowGraph.EDGE_KEY_FALSE, DataFlowItem.DOES_NOT_EXIT); 89 } 90 91 return m; 92 } 93 94 return itemToMap(in, succEdgeKeys); 95 } 96 97 98 public Item confluence(List inItems, Term node, FlowGraph graph) { 99 for (Iterator i = inItems.iterator(); i.hasNext(); ) { 101 if (!((DataFlowItem)i.next()).exits) { 102 return DataFlowItem.DOES_NOT_EXIT; 103 } 104 } 105 return DataFlowItem.EXITS; 106 } 107 108 public void check(FlowGraph graph, Term n, Item inItem, Map outItems) throws SemanticException { 109 if (n == graph.entryNode()) { 115 if (outItems != null && !outItems.isEmpty()) { 116 DataFlowItem outItem = (DataFlowItem)outItems.values().iterator().next(); 119 if (outItem != null && !outItem.exits) { 120 throw new SemanticException("Missing return statement.", 121 code.position()); 122 } 123 } 124 } 125 } 126 } 127 | Popular Tags |