import ceylon.language.impl { BaseIterable, BaseIterator } "Need a map-like thing, but can't use java.util.HashMap directly, not ceylon.collection::HashMap" native class NativeMap<Key,Element>() { shared native Element? get(Key id); shared native void put(Key id, Element instanceOrPartial); shared native Boolean contains(Key id); shared native {Key*} keys; shared native {Element*} items; shared native Integer size; shared native actual String string; } native("jvm") class NativeMap<Key,Element>() { import java.util { HashMap, JavaIterator=Iterator } native("jvm") HashMap<Key, Element> m = HashMap<Key, Element>(); shared native("jvm") void put(Key id, Element instanceOrPartial) { m.put(id, instanceOrPartial); } shared native("jvm") Element? get(Key id) { return m.get(id of Object?); } shared native("jvm") Boolean contains(Key id) { return m.containsKey(id of Object?); } shared native("jvm") Integer size { return m.size(); } shared native("jvm") Iterable<Element, Null> items { return object extends BaseIterable<Element,Null>() satisfies Identifiable { shared actual Iterator<Element> iterator() { JavaIterator<Element> it = m.values().iterator(); return object extends BaseIterator<Element>() satisfies Identifiable { shared actual Element|Finished next() { if (it.hasNext()) { return it.next(); } else { return finished; } } }; } }; } shared native("jvm") Iterable<Key, Null> keys { return object extends BaseIterable<Key,Null>() satisfies Identifiable { shared actual Iterator<Key> iterator() { JavaIterator<Key> it = m.keySet().iterator(); return object extends BaseIterator<Key>() satisfies Identifiable { shared actual Key|Finished next() { if (it.hasNext()) { return it.next(); } else { return finished; } } }; } }; } shared native("jvm") actual String string { return m.string; } } native("js") class NativeMap<Key,Element>() { dynamic ks; dynamic vs; dynamic { ks = dynamic[null]; vs = dynamic[null]; } "Find the index of the specified key, or -1 if it isn't in the map" Integer find(Key id) { if (id exists) { dynamic { Integer len=ks.length; if (len < 2) { return -1; } for (i in 1:len-1) { if (id == ks[i]) { return i; } } } return -1; } return 0; } shared native("js") void put(Key id, Element instanceOrPartial) { value i = find(id); if (i >= 0) { //replace dynamic { setObjectProperty(vs, i, instanceOrPartial); } } else if (i < 0) { //new entry dynamic { ks.push(id); vs.push(instanceOrPartial); } } } shared native("js") Element? get(Key id) { value i = find(id); dynamic { return i >= 0 then vs[i] else null; } } shared native("js") Boolean contains(Key id) => find(id) >= 0; shared native("js") Integer size { dynamic { return ks.length-1; } } shared native("js") Iterable<Element, Null> items { return object extends BaseIterable<Element,Null>() satisfies Identifiable { shared actual Iterator<Element> iterator() { variable value i=1; return object extends BaseIterator<Element>() satisfies Identifiable { shared actual Element|Finished next() { dynamic { if (i >= vs.length) { return finished; } Element e = vs[i]; i++; return e; } } }; } }; } shared native("js") Iterable<Key, Null> keys { return object extends BaseIterable<Key,Null>() satisfies Identifiable { shared actual Iterator<Key> iterator() { variable value i=1; return object extends BaseIterator<Key>() satisfies Identifiable { shared actual Key|Finished next() { dynamic { if (i >= ks.length) { return finished; } Key e = ks[i]; i++; return e; } } }; } }; } shared native("js") actual String string { value sb=StringBuilder(); sb.append("{"); dynamic { if (vs[0] exists) { sb.append("<null> ->").append(vs[0].string); } if (ks.length>1) { for (i in 1:ks.length-1) { if (sb.size > 1) { sb.append(", "); } sb.append(ks[i]).append("->"); if (vs[i] exists) { sb.append(vs[i].string); } else { sb.append("[null]"); } } } } sb.append("}"); return sb.string; } }