/** * The confluence operator is essentially the union of all of the inItems. However, if two or more * of the initCount maps from the inItems each have a MinMaxInitCounts entry for the same * VarInstance, the conflict must be resolved, by using the minimum of all mins and the maximum of * all maxs. */ public Item confluence(List inItems, Term node, FlowGraph graph) { // Resolve any conflicts pairwise. Iterator iter = inItems.iterator(); Map m = null; while (iter.hasNext()) { Item itm = (Item) iter.next(); if (itm == BOTTOM) continue; if (m == null) { m = new HashMap(((DataFlowItem) itm).initStatus); } else { Map n = ((DataFlowItem) itm).initStatus; for (Iterator iter2 = n.entrySet().iterator(); iter2.hasNext(); ) { Map.Entry entry = (Map.Entry) iter2.next(); VarInstance v = (VarInstance) entry.getKey(); MinMaxInitCount initCount1 = (MinMaxInitCount) m.get(v); MinMaxInitCount initCount2 = (MinMaxInitCount) entry.getValue(); m.put(v, MinMaxInitCount.join(initCount1, initCount2)); } } } if (m == null) return BOTTOM; return new DataFlowItem(m); }
/** * Check that each static final field is initialized exactly once. * * @param cb The ClassBody of the class declaring the fields to check. * @throws SemanticException */ protected void checkStaticFinalFieldsInit(ClassBody cb) throws SemanticException { // check that all static fields have been initialized exactly once. for (Iterator iter = currCBI.currClassFinalFieldInitCounts.entrySet().iterator(); iter.hasNext(); ) { Map.Entry e = (Map.Entry) iter.next(); if (e.getKey() instanceof FieldInstance) { FieldInstance fi = (FieldInstance) e.getKey(); if (fi.flags().isStatic() && fi.flags().isFinal()) { MinMaxInitCount initCount = (MinMaxInitCount) e.getValue(); if (InitCount.ZERO.equals(initCount.getMin())) { throw new SemanticException( "field \"" + fi.name() + "\" might not have been initialized", cb.position()); } } } } }
/** Perform necessary actions upon seeing the Initializer <code>initializer</code>. */ protected void finishInitializer( FlowGraph graph, Initializer initializer, DataFlowItem dfIn, DataFlowItem dfOut) { // We are finishing the checking of an intializer. // We need to copy back the init counts of any fields back into // currClassFinalFieldInitCounts, so that the counts are // correct for the next initializer or constructor. Iterator iter = dfOut.initStatus.entrySet().iterator(); while (iter.hasNext()) { Map.Entry e = (Map.Entry) iter.next(); if (e.getKey() instanceof FieldInstance) { FieldInstance fi = (FieldInstance) e.getKey(); if (fi.flags().isFinal()) { // we don't need to join the init counts, as all // dataflows will go through all of the // initializers currCBI.currClassFinalFieldInitCounts.put(fi, e.getValue()); } } } }