public static void decRefs(Dictionary dict) { dict.refCount--; if (dict.refCount == 0) { for (Map.Entry e : dict.entrySet()) { decRefs(e.getKey()); decRefs(e.getValue()); } } }
/** * Decrement the reference count for this object. In some cases, this may have no effect. In other * cases, the current reference count will be maintained and in-place updates can only occur when * the reference count is one. */ public static void decRefs(Object obj) { if (obj instanceof List) { List list = (List) obj; list.refCount--; if (list.refCount == 0) { for (Object o : list) { decRefs(o); } } } else if (obj instanceof Record) { Record rec = (Record) obj; rec.refCount--; if (rec.refCount == 0) { for (Object o : rec.values()) { decRefs(o); } } } else if (obj instanceof Set) { Set set = (Set) obj; set.refCount--; if (set.refCount == 0) { for (Object o : set) { decRefs(o); } } } else if (obj instanceof Dictionary) { Dictionary dict = (Dictionary) obj; dict.refCount--; if (dict.refCount == 0) { for (Map.Entry e : dict.entrySet()) { decRefs(e.getKey()); decRefs(e.getValue()); } } } else if (obj instanceof Tuple) { Tuple tuple = (Tuple) obj; tuple.refCount--; if (tuple.refCount == 0) { for (Object o : tuple) { decRefs(o); } } } }
/** * This method gets called when we're testing a dictionary object against some type. To reduce the * number of cases, we can narrow down the possible types by a process of deduction. The type * cannot be <code>void</code> or <code>any</code> (since the test would already have been * eliminated). Likewise, it cannot be e.g. a record, since again the test would already have been * eliminated. In fact, the type can only be a dictionary or its negation. * * @param object --- object being tested against. * @param type --- type to test against. * @return */ public static boolean instanceOf(Dictionary object, Type type) { if (type instanceof Type.Dictionary) { Type.Dictionary tl = (Type.Dictionary) type; Type key = tl.key; Type value = tl.value; if (key.kind == K_ANY && value.kind == K_ANY) { return true; } else if (key.kind == K_VOID || value.kind == K_VOID) { return object.isEmpty(); } else { for (java.util.Map.Entry<Object, Object> elem : object.entrySet()) { if (!instanceOf(elem.getKey(), key) || !instanceOf(elem.getValue(), value)) { return false; } } return true; } } else { return instanceOf((Object) object, type); } }
/** The <code>instanceOf</code> method implements a runtime type test. */ public static boolean instanceOf(Object obj, Type t) { switch (t.kind) { case K_ANY: return true; case K_VOID: return false; case K_NULL: return obj == null; case K_BOOL: return obj instanceof Boolean; case K_BYTE: return obj instanceof Byte; case K_CHAR: return obj instanceof Character; case K_INT: return obj instanceof BigInteger; case K_RATIONAL: return obj instanceof BigRational; case K_STRING: return obj instanceof String; case K_LIST: { if (obj instanceof List) { List ol = (List) obj; Type.List tl = (Type.List) t; if (tl.nonEmpty && ol.isEmpty()) { return false; } Type el = tl.element; if (el.kind == K_ANY) { return true; } else if (el.kind == K_VOID) { return ol.isEmpty(); } else { for (Object elem : ol) { if (!instanceOf(elem, el)) { return false; } } return true; } } break; } case K_SET: { if (obj instanceof Set) { Set ol = (Set) obj; Type.Set tl = (Type.Set) t; Type el = tl.element; if (el.kind == K_ANY) { return true; } else if (el.kind == K_VOID) { return ol.isEmpty(); } else { for (Object elem : ol) { if (!instanceOf(elem, el)) { return false; } } return true; } } break; } case K_TUPLE: { if (obj instanceof Tuple) { Tuple ol = (Tuple) obj; Type.Tuple tl = (Type.Tuple) t; Type[] types = tl.types; if (types.length == ol.size()) { int i = 0; for (Object o : ol) { if (!instanceOf(o, types[i++])) { return false; } } return true; } } break; } case K_DICTIONARY: { if (obj instanceof Dictionary) { Dictionary ol = (Dictionary) obj; Type.Dictionary tl = (Type.Dictionary) t; Type key = tl.key; Type value = tl.value; if (key.kind == K_ANY && value.kind == K_ANY) { return true; } else if (key.kind == K_VOID || value.kind == K_VOID) { return ol.isEmpty(); } else { for (java.util.Map.Entry<Object, Object> elem : ol.entrySet()) { if (!instanceOf(elem.getKey(), key) || !instanceOf(elem.getValue(), value)) { return false; } } return true; } } break; } case K_RECORD: { if (obj instanceof Record) { Record ol = (Record) obj; Type.Record tl = (Type.Record) t; String[] names = tl.names; Type[] types = tl.types; if (!tl.isOpen && names.length != ol.size()) { return false; } for (int i = 0; i != names.length; ++i) { String name = names[i]; if (ol.containsKey(name)) { Type type = types[i]; Object val = ol.get(name); if (!instanceOf(val, type)) { return false; } } else { return false; } } return true; } break; } case K_NEGATION: { Type.Negation not = (Type.Negation) t; return !instanceOf(obj, not.element); } case K_UNION: { Type.Union un = (Type.Union) t; for (Type bound : un.bounds) { if (instanceOf(obj, bound)) { return true; } } break; } } return false; }
public static void countClone(Dictionary l) { ndict_clones++; ndict_elems += l.size(); }