public static Map<String, Long> getClassSVUIDs(SJSessionType sjtype) throws SJIOException, ClassNotFoundException { HashMap<String, Long> ours = new HashMap<String, Long>(); while (sjtype != null) { if (sjtype instanceof SJOutbranchType) { SJOutbranchType obt = (SJOutbranchType) sjtype; for (SJLabel lab : obt.labelSet()) { ours.putAll(getClassSVUIDs(obt.branchCase(lab))); } } else if (sjtype instanceof SJInbranchType) { SJInbranchType ibt = (SJInbranchType) sjtype; for (SJLabel lab : ibt.labelSet()) { ours.putAll(getClassSVUIDs(ibt.branchCase(lab))); } } else if (sjtype instanceof SJOutwhileType) { ours.putAll(getClassSVUIDs(((SJOutwhileType) sjtype).body())); } else if (sjtype instanceof SJInwhileType) { ours.putAll(getClassSVUIDs(((SJInwhileType) sjtype).body())); } else if (sjtype instanceof SJRecursionType) { ours.putAll(getClassSVUIDs(((SJRecursionType) sjtype).body())); } else if (sjtype instanceof SJSendType) { ours.putAll(getMessageSVUID(((SJSendType) sjtype).messageType())); } else if (sjtype instanceof SJReceiveType) { ours.putAll(getMessageSVUID(((SJReceiveType) sjtype).messageType())); } else if (sjtype instanceof SJRecurseType) { // Nothing to do. } sjtype = sjtype.child(); } return ours; }
// Recursively visits each element of a session type. Collects recursion scope labels and checks // that all recurse are bound. Also checks that an element with a recurse has no child at any // lexical level up to the outermost recursion scope (only tail recursion permitted). private void wellFormedRecursionsAux(SJSessionType st, Set<SJLabel> labs, Set<SJLabel> jumps) throws SemanticException { if (st == null) // For empty branch cases and loop bodies. { return; } if (st instanceof SJRecurseType) { SJRecurseType sjrt = (SJRecurseType) st; SJLabel lab = sjrt.label(); if (!labs.contains(lab)) { throw new SemanticException("[SJTypeSystem_c] Recurse label not bound: " + sjrt); } jumps.add(lab); } else if (st instanceof SJLoopType) // Compound types. { if (st instanceof SJRecursionType) { SJRecursionType sjrt = (SJRecursionType) st; SJLabel lab = sjrt.label(); if (labs.contains(lab)) { throw new SemanticException("[SJTypeSystem_c] Label already in scope: " + lab); } labs.add(lab); wellFormedRecursionsAux(sjrt.body(), labs, jumps); labs.remove(lab); jumps.remove(lab); } else { wellFormedRecursionsAux( ((SJLoopType) st).body(), new HashSet<SJLabel>(), jumps); // Empty labs set, so can't jump out. } } else if (st instanceof SJBranchType) { SJBranchType sjobt = (SJBranchType) st; Set<SJLabel> next = new HashSet<SJLabel>(); for (SJLabel lab : sjobt.labelSet()) { Set<SJLabel> current = new HashSet<SJLabel>(); current.addAll(jumps); wellFormedRecursionsAux(sjobt.branchCase(lab), labs, current); next.addAll(current); } jumps.addAll(next); } if (st.child() != null) // Handles basic types. { if (!jumps.isEmpty()) { throw new SemanticException("[SJTypeSystem_c] Only tail recursion is permitted [2]: " + st); } wellFormedRecursionsAux(st.child(), labs, jumps); // jumps is empty. } return; }