package tracematches; import java.util.*; public class HasNext { static aspect HashNextCheck{ tracematch(Iterator i) { sym hasNext before: call(* java.util.Iterator+.hasNext()) && target(i); sym next before: call(* java.util.Iterator+.next()) && target(i); next next { if(System.getProperty("TMTEST_ACTIVE")!=null) { throw new RuntimeException("Should call 'boolean Iterator.hasNext()'"); } } } } public static void main(String[] args) { //unsafe Collection c = new ArrayList(); c.add(""); c.add(""); Iterator iterator = c.iterator(); System.out.println("n1"); iterator.next(); iterator.hasNext(); System.out.println("n2"); iterator.next(); System.out.println("n3"); iterator.next(); //safe but not detected as such (needs must-point-to info) Collection c2 = new ArrayList(); for (Iterator i2 = c2.iterator(); i2.hasNext();) { i2.next(); } } }