From fe8abfc35440c00d9a116bfebe1b58ff2fe2eff7 Mon Sep 17 00:00:00 2001 From: Reino Ruusu Date: Fri, 7 Oct 2016 21:54:29 +0300 Subject: [PATCH] Databoard and SCL enchancements. Mapping for generic java.util.Map and java.util.Set references. Moved databoard-related SCL definitions to a new Databoard module. Added documentation string to Databoard.scl. Added a few SCL bindings to potentially useful methods in the Binding class. refs #6738 Change-Id: I07369ca5a5ae23966b11ce5ff9787ab07e38af29 --- .../factory/DefaultBindingFactory.java | 6 +- .../factory/JavaUtilBindingsProvider.java | 6 +- .../factory/TroveBindingsProvider.java | 9 +- .../binding/impl/DefaultMapBinding.java | 326 ++++++++++++++++++ .../binding/impl/DefaultSetBinding.java | 239 +++++++++++++ .../binding/impl/HashMapBinding.java | 17 +- .../binding/impl/HashSetBinding.java | 7 +- .../binding/impl/TreeSetBinding.java | 15 +- .../compiler/constants/JavaMathOperation.java | 10 + .../compiler/elaboration/java/JavaModule.java | 18 +- .../constraints/ReduceSerializable.java | 4 +- .../org.simantics.scl.db/scl/Simantics/DB.scl | 25 -- .../scl/Databoard.scl | 279 +++++++++++++++ .../org.simantics.scl.runtime/scl/Prelude.scl | 125 ++----- .../scl/StandardLibrary.scl | 1 + 15 files changed, 945 insertions(+), 142 deletions(-) create mode 100644 bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/DefaultMapBinding.java create mode 100644 bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/DefaultSetBinding.java create mode 100644 bundles/org.simantics.scl.runtime/scl/Databoard.scl diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/DefaultBindingFactory.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/DefaultBindingFactory.java index 54c1160c5..73f2d2f16 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/DefaultBindingFactory.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/DefaultBindingFactory.java @@ -20,6 +20,7 @@ import org.simantics.databoard.binding.impl.BooleanArrayBinding; import org.simantics.databoard.binding.impl.BooleanBindingDefault; import org.simantics.databoard.binding.impl.ByteArrayBinding; import org.simantics.databoard.binding.impl.ByteBindingDefault; +import org.simantics.databoard.binding.impl.DefaultMapBinding; import org.simantics.databoard.binding.impl.DoubleArrayBinding; import org.simantics.databoard.binding.impl.DoubleBindingDefault; import org.simantics.databoard.binding.impl.FloatArrayBinding; @@ -30,7 +31,6 @@ import org.simantics.databoard.binding.impl.LongArrayBinding; import org.simantics.databoard.binding.impl.LongBindingDefault; import org.simantics.databoard.binding.impl.ObjectArrayBinding; import org.simantics.databoard.binding.impl.StringBindingDefault; -import org.simantics.databoard.binding.impl.TreeMapBinding; import org.simantics.databoard.binding.mutable.ContainerOptionalBinding; import org.simantics.databoard.binding.mutable.UnionTaggedObjectBinding; import org.simantics.databoard.type.ArrayType; @@ -180,9 +180,9 @@ public class DefaultBindingFactory extends TypeBindingFactory { return binding; } - if (type instanceof MapType) { + if (type instanceof MapType) { MapType mapType = (MapType) type; - TreeMapBinding binding = new TreeMapBinding(mapType, null, null); + DefaultMapBinding binding = new DefaultMapBinding(mapType, null, null); inprogress.put(type, binding); binding.setKeyBinding( construct(mapType.keyType) ); binding.setValueBinding( construct(mapType.valueType) ); diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/JavaUtilBindingsProvider.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/JavaUtilBindingsProvider.java index e43b7bc73..b173cb6eb 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/JavaUtilBindingsProvider.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/JavaUtilBindingsProvider.java @@ -28,6 +28,8 @@ import org.simantics.databoard.binding.error.BindingConstructionException; import org.simantics.databoard.binding.impl.ArrayListBinding; import org.simantics.databoard.binding.impl.BooleanArrayBinding; import org.simantics.databoard.binding.impl.ByteArrayBinding; +import org.simantics.databoard.binding.impl.DefaultMapBinding; +import org.simantics.databoard.binding.impl.DefaultSetBinding; import org.simantics.databoard.binding.impl.DoubleArrayBinding; import org.simantics.databoard.binding.impl.FloatArrayBinding; import org.simantics.databoard.binding.impl.HashMapBinding; @@ -101,7 +103,7 @@ public class JavaUtilBindingsProvider implements BindingProvider { if (Set.class.isAssignableFrom(request.getClazz())) { MapType type = new MapType(); type.valueType = Datatypes.VOID; - return new TreeSetBinding(type, null); + return new DefaultSetBinding(type, null); } if (TreeMap.class.isAssignableFrom(request.getClazz())) { @@ -113,7 +115,7 @@ public class JavaUtilBindingsProvider implements BindingProvider { } if (Map.class.isAssignableFrom(request.getClazz())) { - return new HashMapBinding(new MapType(), null, null); + return new DefaultMapBinding(new MapType(), null, null); } return null; diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/TroveBindingsProvider.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/TroveBindingsProvider.java index e635e12a0..0f9a4dc76 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/TroveBindingsProvider.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/factory/TroveBindingsProvider.java @@ -103,6 +103,9 @@ public class TroveBindingsProvider implements BindingProvider { @Override public Object create(Map initialMap) throws BindingException { + if (initialMap instanceof THashMap) + return initialMap; + // Replace with TreeMap. Create comparator from binding. THashMap result = new THashMap(); putAll(result, initialMap); @@ -134,10 +137,14 @@ public class TroveBindingsProvider implements BindingProvider { } public Object create(Set initialSet) throws BindingException { + if (initialSet instanceof THashSet) + return initialSet; + return new THashSet(initialSet); } - @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override public Object create(Map initialMap) throws BindingException { return new THashSet(initialMap.keySet()); } diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/DefaultMapBinding.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/DefaultMapBinding.java new file mode 100644 index 000000000..43c1e97aa --- /dev/null +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/DefaultMapBinding.java @@ -0,0 +1,326 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.databoard.binding.impl; + +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +import org.simantics.databoard.binding.ArrayBinding; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.MapBinding; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.type.MapType; + +/** + * Binds java.util.Map to MapType + * + * This Binding type accepts all java.util.Map instances, but creates + * java.util.TreeMap instances by default. + * + * @author Reino Ruusu + */ +@SuppressWarnings("rawtypes") +public class DefaultMapBinding extends MapBinding { + + public DefaultMapBinding(Binding keyBinding, Binding valueBinding) { + super(keyBinding, valueBinding); + } + + public DefaultMapBinding(MapType mapType, Binding keyBinding, + Binding valueBinding) { + super(mapType, keyBinding, valueBinding); + } + + public void postConstruction() { + } + + @Override + public Object create() { + return new TreeMap( keyBinding ); + } + + @SuppressWarnings("unchecked") + @Override + public Object create(Object[] keys, Object[] values) { + if (keys.length != values.length) + throw new IllegalArgumentException("Equal length arrays expected"); + + int len = keys.length; + Map result = new TreeMap( keyBinding ); + + for (int i = 0; i < len; i++) { + Object key = keys[i]; + Object value = values[i]; + result.put(key, value); + } + + return result; + } + + + @SuppressWarnings("unchecked") + @Override + public Object create(List keys, List values) { + if (keys.size()!=values.size()) + throw new IllegalArgumentException("Equal length arrays expected"); + + int len = keys.size(); + Map result = new TreeMap( keyBinding ); + + for (int i=0; i map) { + return map; + } + + @Override + public void clear(Object map) { + ((Map) map).clear(); + } + + @Override + public boolean containsKey(Object map, Object key) { + Map m = ((Map) map); + return m.containsKey(key); + } + + @Override + public boolean containsValue(Object map, Object value) { + Map m = ((Map) map); + Binding vb = getValueBinding(); + for (Object v : m.values()) + { + if (vb.equals(v, value)) return true; + } + return false; + } + + @Override + public Object get(Object map, Object key) { + Map m = ((Map) map); + return m.get(key); + } + + @SuppressWarnings("unchecked") + @Override + public Object[] getKeys(Object map) { + Map m = ((Map) map); + return m.keySet().toArray(new Object[m.size()]); + } + + @SuppressWarnings("unchecked") + @Override + public void getKeys(Object map, Set keys) throws BindingException { + Map m = ((Map)map); + keys.addAll(m.keySet()); + } + + /** + * Count the number of entries between two keyes + * @param from + * @param fromInclusive + * @param end + * @param endInclusive + * @throws BindingException + */ + @SuppressWarnings("unchecked") + @Override + public int count(Object src, Object from, boolean fromInclusive, Object end, boolean endInclusive) throws BindingException { + // Assert end > from + if (keyBinding.compare(from, end)>0) return 0; + + if (src instanceof TreeMap) { + TreeMap m = (TreeMap) src; + Map sm = m.subMap(from, fromInclusive, end, endInclusive); + return sm.size(); + } + else { + int result = 0; + Map m = ((Map)src); + for (Object k : m.keySet()) { + int fk = keyBinding.compare(from, k); + int ek = keyBinding.compare(k, end); + boolean fromMatches = fromInclusive ? fk<=0 : fk<0; + boolean endMatches = endInclusive ? ek<=0 : ek <0; + if ( fromMatches && endMatches ) result++; + } + return result; + } + } + + /** + * Read a range of entries + * + * @param src + * @param from + * @param fromInclusive + * @param end + * @param endInclusive + * @param dstKeyArrayBinding + * @param dstKeyArray + * @param dstValueArrayBinding + * @param dstValueArray + * @throws BindingException + */ + public int getEntries(Object src, Object from, boolean fromInclusive, Object end, boolean endInclusive, ArrayBinding dstKeyArrayBinding, Object dstKeyArray, ArrayBinding dstValueArrayBinding, Object dstValueArray, int limit) throws BindingException { + if (src instanceof TreeMap) { + return new TreeMapBinding(keyBinding, valueBinding).getEntries(src, from, fromInclusive, end, endInclusive, dstKeyArrayBinding, dstKeyArray, dstValueArrayBinding, dstValueArray, limit); + } + else { + return new HashMapBinding(keyBinding, valueBinding).getEntries(src, from, fromInclusive, end, endInclusive, dstKeyArrayBinding, dstKeyArray, dstValueArrayBinding, dstValueArray, limit); + } + } + + + @SuppressWarnings("unchecked") + @Override + public Object[] getValues(Object map) { + Map m = ((Map) map); + return m.values().toArray(new Object[m.size()]); + } + + @Override + public void put(Object map, K key, V value) { + @SuppressWarnings("unchecked") + Map m = ((Map) map); + m.put(key, value); + } + + @Override + public void putAll(Object dstMap, Map srcMap) { + @SuppressWarnings("unchecked") + Map dst = ((Map) dstMap); + dst.putAll(srcMap); + } + + @SuppressWarnings("unchecked") + @Override + public void getAll(Object mapFrom, Map to) { + Map m = ((Map) mapFrom); + to.putAll(m); + } + + @SuppressWarnings("unchecked") + @Override + public void getAll(Object mapFrom, Object[] keys, Object[] values) { + Map m = (Map) mapFrom; + int i = 0; + for (Entry e : (Set>) m.entrySet()) { + keys[i] = e.getKey(); + values[i] = e.getValue(); + i++; + } + } + + @Override + public Object remove(Object map, Object key) { + Map m = ((Map) map); + return m.remove(key); + } + + @Override + public int size(Object map) { + Map m = ((Map) map); + return m.size(); + } + + @Override + public boolean isInstance(Object obj) { + return obj instanceof Map; + } + + @Override + public int deepHashValue(Object map, IdentityHashMap hashedObjects) throws BindingException { + int result = 0; + Map m = ((Map) map); + @SuppressWarnings("unchecked") + Set s = m.entrySet(); + for (Entry e : s) { + int keyTree = getKeyBinding().deepHashValue(e.getKey(), hashedObjects); + int valueTree = getValueBinding().deepHashValue(e.getValue(), hashedObjects); + result += (keyTree ^ valueTree); + } + return result; + } + + @Override + public Object getCeilingKey(Object map, Object key) { + if (map instanceof TreeMap) { + return new TreeMapBinding(keyBinding, valueBinding).getCeilingKey(map, key); + } + else { + return new HashMapBinding(keyBinding, valueBinding).getCeilingKey(map, key); + } + } + + @Override + public Object getFirstKey(Object map) { + if (map instanceof TreeMap) { + return new TreeMapBinding(keyBinding, valueBinding).getFirstKey(map); + } + else { + return new HashMapBinding(keyBinding, valueBinding).getFirstKey(map); + } + } + + @Override + public Object getFloorKey(Object map, Object key) { + if (map instanceof TreeMap) { + return new TreeMapBinding(keyBinding, valueBinding).getFloorKey(map, key); + } + else { + return new HashMapBinding(keyBinding, valueBinding).getFloorKey(map, key); + } + } + + @Override + public Object getHigherKey(Object map, Object key) { + if (map instanceof TreeMap) { + return new TreeMapBinding(keyBinding, valueBinding).getHigherKey(map, key); + } + else { + return new HashMapBinding(keyBinding, valueBinding).getHigherKey(map, key); + } + } + + @Override + public Object getLastKey(Object map) { + if (map instanceof TreeMap) { + return new TreeMapBinding(keyBinding, valueBinding).getLastKey(map); + } + else { + return new HashMapBinding(keyBinding, valueBinding).getLastKey(map); + } + } + + @Override + public Object getLowerKey(Object map, Object key) { + if (map instanceof TreeMap) { + return new TreeMapBinding(keyBinding, valueBinding).getLowerKey(map, key); + } + else { + return new HashMapBinding(keyBinding, valueBinding).getLowerKey(map, key); + } + } +} diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/DefaultSetBinding.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/DefaultSetBinding.java new file mode 100644 index 000000000..783f80b33 --- /dev/null +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/DefaultSetBinding.java @@ -0,0 +1,239 @@ +/******************************************************************************* + * Copyright (c) 2010 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.databoard.binding.impl; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.simantics.databoard.binding.ArrayBinding; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.MapBinding; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.binding.reflection.VoidBinding; +import org.simantics.databoard.type.MapType; +import org.simantics.databoard.type.RecordType; + +/** + * Binds java.util.Set to Map(T, {}) + * + * This binding accepts all java.util.Set instances, but instantiates + * java.util.TreeSet objects. + * + * @author Reino Ruusu + */ +@SuppressWarnings("unchecked") +public class DefaultSetBinding extends MapBinding { + + public DefaultSetBinding(MapType mapType, Binding elementBinding) { + super(mapType, elementBinding, VoidBinding.VOID_BINDING); + } + + public DefaultSetBinding(Binding elementBinding) { + super(new MapType(elementBinding.type(), RecordType.VOID_TYPE), elementBinding, VoidBinding.VOID_BINDING); + } + + @Override + public void clear(Object set) throws BindingException { + Set _set = (Set) set; + _set.clear(); + } + + @Override + public boolean containsKey(Object set, Object key) throws BindingException { + Set _set = (Set) set; + return _set.contains(key); + } + + @Override + public boolean containsValue(Object set, Object value) + throws BindingException { + return false; + } + + @Override + public Object create() throws BindingException { + return new TreeSet( keyBinding ); + } + + public Object create(Set initialSet) throws BindingException { + return initialSet; + } + + @Override + public Object create(Map initialMap) throws BindingException { + Set result = new TreeSet( keyBinding ); + result.addAll(initialMap.keySet()); + return result; + } + + @Override + public Object create(Object[] keys, Object[] values) + throws BindingException { + Set result = new TreeSet( keyBinding ); + for (int i=0; i keys, List values) { + Set result = new TreeSet( keyBinding ); + for (int i=0; i void getAll(Object setFrom, Map to) throws BindingException { + Map _to = (Map) to; + Set _setFrom = (Set) setFrom; + for (K k : _setFrom) + _to.put(k, null); + } + + @Override + public void getAll(Object setFrom, Object[] keys, Object[] values) + throws BindingException { + Set _setFrom = (Set) setFrom; + int i=0; + for (Object k : _setFrom) { + keys[i] = k; + values[i] = null; + } + } + + @Override + public Object[] getKeys(Object set) throws BindingException { + Set _set = (Set) set; + return _set.toArray(new Object[_set.size()]); + } + + @Override + public void getKeys(Object set, Set keys) throws BindingException { + Set s = (Set) set; + keys.addAll(s); + } + + @Override + public Object[] getValues(Object set) throws BindingException { + Set _set = (Set) set; + return new Object[_set.size()]; + } + + @Override + public int count(Object src, Object from, boolean fromInclusive, Object end, boolean endInclusive) throws BindingException { + if (src instanceof TreeSet) + return new TreeSetBinding(keyBinding).count(src, from, fromInclusive, end, endInclusive); + else + return new HashSetBinding(keyBinding).count(src, from, fromInclusive, end, endInclusive); + } + + @Override + public int getEntries(Object src, Object from, boolean fromInclusive, Object end, boolean endInclusive, ArrayBinding dstKeyArrayBinding, Object dstKeyArray, ArrayBinding dstValueArrayBinding, Object dstValueArray, int limit) throws BindingException { + return 0; + } + + @Override + public void put(Object set, Object key, Object value) + throws BindingException { + Set _set = (Set) set; + if (value!=null) throw new BindingException("Cannot put non-null to a Set"); + _set.add(key); + } + + public void putAll(Object setTo, Set from) { + Set _set = (Set) setTo; + _set.addAll(from); + } + + @Override + public void putAll(Object setTo, Map from) throws BindingException { + Set _set = (Set) setTo; + _set.addAll(from.keySet()); + } + + @Override + public Object remove(Object set, Object key) throws BindingException { + Set _set = (Set) set; + _set.remove(key); + return null; + } + + @Override + public int size(Object set) throws BindingException { + Set _set = (Set) set; + return _set.size(); + } + + @Override + public boolean isInstance(Object obj) { + return obj instanceof Set; + } + + @Override + public Object getCeilingKey(Object set, Object key) { + if (set instanceof TreeSet) + return new TreeSetBinding(keyBinding).getCeilingKey(set, key); + else + return new HashSetBinding(keyBinding).getCeilingKey(set, key); + } + + @Override + public Object getFirstKey(Object set) { + if (set instanceof TreeSet) + return new TreeSetBinding(keyBinding).getFirstKey(set); + else + return new HashSetBinding(keyBinding).getFirstKey(set); + } + + @Override + public Object getFloorKey(Object set, Object key) { + if (set instanceof TreeSet) + return new TreeSetBinding(keyBinding).getFloorKey(set, key); + else + return new HashSetBinding(keyBinding).getFloorKey(set, key); + } + + @Override + public Object getHigherKey(Object set, Object key) { + if (set instanceof TreeSet) + return new TreeSetBinding(keyBinding).getHigherKey(set, key); + else + return new HashSetBinding(keyBinding).getHigherKey(set, key); + } + + @Override + public Object getLastKey(Object set) { + if (set instanceof TreeSet) + return new TreeSetBinding(keyBinding).getLastKey(set); + else + return new HashSetBinding(keyBinding).getLastKey(set); + } + + @Override + public Object getLowerKey(Object set, Object key) { + if (set instanceof TreeSet) + return new TreeSetBinding(keyBinding).getLowerKey(set, key); + else + return new HashSetBinding(keyBinding).getLowerKey(set, key); + } + +} + diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/HashMapBinding.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/HashMapBinding.java index d3a9d8c75..76241a0c7 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/HashMapBinding.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/HashMapBinding.java @@ -53,13 +53,11 @@ public class HashMapBinding extends MapBinding { super(mapType, keyBinding, valueBinding); } - public void postConstruction() {} - - @Override - public Object create() { - return new HashMap(); - } - + @Override + public Object create() { + return new HashMap(); + } + @Override public Object create(Object[] keys, Object[] values) { if (keys.length!=values.length) @@ -97,7 +95,10 @@ public class HashMapBinding extends MapBinding { } @Override - public Object create(Map initialMap) throws BindingException { + public Object create(Map initialMap) throws BindingException { + if (initialMap instanceof HashMap) + return initialMap; + // Replace with TreeMap. Create comparator from binding. HashMap result = new HashMap(); putAll(result, initialMap); diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/HashSetBinding.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/HashSetBinding.java index efeb38493..494b3d9e8 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/HashSetBinding.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/HashSetBinding.java @@ -32,7 +32,7 @@ import org.simantics.databoard.type.RecordType; * * @author Toni Kalajainen */ -@SuppressWarnings("all") +@SuppressWarnings({"rawtypes", "unchecked"}) public class HashSetBinding extends MapBinding { public HashSetBinding(MapType mapType, Binding elementBinding) { @@ -43,7 +43,6 @@ public class HashSetBinding extends MapBinding { super(new MapType(elementBinding.type(), RecordType.VOID_TYPE), elementBinding, VoidBinding.VOID_BINDING); } - @SuppressWarnings("unchecked") @Override public void clear(Object set) throws BindingException { Set _set = (Set) set; @@ -139,7 +138,6 @@ public class HashSetBinding extends MapBinding { keys.addAll(s); } - @SuppressWarnings("unchecked") @Override public int count(Object src, Object from, boolean fromInclusive, Object end, boolean endInclusive) throws BindingException { @@ -183,7 +181,6 @@ public class HashSetBinding extends MapBinding { s.add(key); } - @SuppressWarnings("unchecked") Object getComparableKey(Object set, Object key) { // if (keyIsComparable) return key; @@ -201,11 +198,9 @@ public class HashSetBinding extends MapBinding { _set.addAll(from); } - @SuppressWarnings("unchecked") @Override public void putAll(Object setTo, Map from) throws BindingException { Set s = (Set) setTo; - Binding kb = getKeyBinding(); for (Entry e : (Set>) from.entrySet()) { Object k = getComparableKey(s, e.getKey()); s.remove(k); diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/TreeSetBinding.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/TreeSetBinding.java index 304b3cad4..50028b3a1 100644 --- a/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/TreeSetBinding.java +++ b/bundles/org.simantics.databoard/src/org/simantics/databoard/binding/impl/TreeSetBinding.java @@ -58,12 +58,15 @@ public class TreeSetBinding extends MapBinding { return false; } - @Override - public Object create() throws BindingException { - return new TreeSet( getKeyBinding() ); - } - - public Object create(Set initialSet) throws BindingException { + @Override + public Object create() throws BindingException { + return new TreeSet( getKeyBinding() ); + } + + public Object create(Set initialSet) throws BindingException { + if (initialSet instanceof TreeSet && ((TreeSet) initialSet).comparator() == getKeyBinding()) + return initialSet; + TreeSet result = new TreeSet(getKeyBinding()); result.addAll(initialSet); return result; diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/JavaMathOperation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/JavaMathOperation.java index e13c18563..caf212a61 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/JavaMathOperation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/JavaMathOperation.java @@ -61,6 +61,16 @@ public class JavaMathOperation extends FunctionValue { public static final JavaMathOperation SOR = new JavaMathOperation(Opcodes.IOR, Types.SHORT, Types.SHORT, Types.SHORT); public static final JavaMathOperation SXOR = new JavaMathOperation(Opcodes.IXOR, Types.SHORT, Types.SHORT, Types.SHORT); + public static final JavaMathOperation BADD = new JavaMathOperation(Opcodes.IADD, Types.BYTE, Types.BYTE, Types.BYTE); + public static final JavaMathOperation BSUB = new JavaMathOperation(Opcodes.ISUB, Types.BYTE, Types.BYTE, Types.BYTE); + public static final JavaMathOperation BMUL = new JavaMathOperation(Opcodes.IMUL, Types.BYTE, Types.BYTE, Types.BYTE); + public static final JavaMathOperation BDIV = new JavaMathOperation(Opcodes.IDIV, Types.BYTE, Types.BYTE, Types.BYTE); + public static final JavaMathOperation BREM = new JavaMathOperation(Opcodes.IREM, Types.BYTE, Types.BYTE, Types.BYTE); + public static final JavaMathOperation BNEG = new JavaMathOperation(Opcodes.INEG, Types.BYTE, Types.BYTE); + public static final JavaMathOperation BAND = new JavaMathOperation(Opcodes.IAND, Types.BYTE, Types.BYTE, Types.BYTE); + public static final JavaMathOperation BOR = new JavaMathOperation(Opcodes.IOR, Types.BYTE, Types.BYTE, Types.BYTE); + public static final JavaMathOperation BXOR = new JavaMathOperation(Opcodes.IXOR, Types.BYTE, Types.BYTE, Types.BYTE); + public static final JavaMathOperation CADD = new JavaMathOperation(Opcodes.IADD, Types.CHARACTER, Types.CHARACTER, Types.INTEGER); public static final JavaMathOperation CSUB = new JavaMathOperation(Opcodes.ISUB, Types.INTEGER, Types.CHARACTER, Types.CHARACTER); diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/JavaModule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/JavaModule.java index 39c2dbec6..cb39346e4 100755 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/JavaModule.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/JavaModule.java @@ -56,6 +56,16 @@ public class JavaModule extends ConcreteModule { addValue("sor", JavaMathOperation.SOR); addValue("sxor", JavaMathOperation.SXOR); + addValue("badd", JavaMathOperation.BADD); + addValue("bsub", JavaMathOperation.BSUB); + addValue("bmul", JavaMathOperation.BMUL); + addValue("bdiv", JavaMathOperation.BDIV); + addValue("brem", JavaMathOperation.BREM); + addValue("bneg", JavaMathOperation.BNEG); + addValue("band", JavaMathOperation.BAND); + addValue("bor", JavaMathOperation.BOR); + addValue("bxor", JavaMathOperation.BXOR); + // Conversions for(JavaConversionOperation operation : JavaConversionOperation.OPCODES) addValue(operation.getMnemonic(), operation); @@ -75,6 +85,13 @@ public class JavaModule extends ConcreteModule { addValue("lcmpgt", new JavaComparisonOperation(">", Types.LONG)); addValue("lcmpge", new JavaComparisonOperation(">=", Types.LONG)); + addValue("bcmpeq", new JavaComparisonOperation("==", Types.BYTE)); + addValue("bcmpne", new JavaComparisonOperation("!=", Types.BYTE)); + addValue("bcmplt", new JavaComparisonOperation("<", Types.BYTE)); + addValue("bcmple", new JavaComparisonOperation("<=", Types.BYTE)); + addValue("bcmpgt", new JavaComparisonOperation(">", Types.BYTE)); + addValue("bcmpge", new JavaComparisonOperation(">=", Types.BYTE)); + addValue("scmpeq", new JavaComparisonOperation("==", Types.SHORT)); addValue("scmpne", new JavaComparisonOperation("!=", Types.SHORT)); addValue("scmplt", new JavaComparisonOperation("<", Types.SHORT)); @@ -112,7 +129,6 @@ public class JavaModule extends ConcreteModule { addValue("ifge", new JavaComparisonToZeroOperation(">=")); TVar A = Types.var(Kinds.STAR); - TVar B = Types.var(Kinds.STAR); addValue("unsafeCoerce", UnsafeCoerce.INSTANCE); addValue("equals", new JavaMethod(true, diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ReduceSerializable.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ReduceSerializable.java index ea0276e35..3b7ef9d1c 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ReduceSerializable.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/ReduceSerializable.java @@ -98,8 +98,8 @@ public class ReduceSerializable { private static final THashMap BINDING_CONSTANTS2 = new THashMap(); static { - BINDING_CONSTANTS2.put(MAP, new JavaConstructor("org/simantics/databoard/binding/impl/HashMapBinding", Types.NO_EFFECTS, Types.pred(Types.SERIALIZABLE, Types.apply(MAP, A, B)), Types.pred(Types.SERIALIZABLE, A), Types.pred(Types.SERIALIZABLE, B))); - BINDING_CONSTANTS2.put(MMAP, new JavaConstructor("org/simantics/databoard/binding/impl/HashMapBinding", Types.NO_EFFECTS, Types.pred(Types.SERIALIZABLE, Types.apply(MMAP, A, B)), Types.pred(Types.SERIALIZABLE, A), Types.pred(Types.SERIALIZABLE, B))); + BINDING_CONSTANTS2.put(MAP, new JavaConstructor("org/simantics/databoard/binding/impl/DefaultMapBinding", Types.NO_EFFECTS, Types.pred(Types.SERIALIZABLE, Types.apply(MAP, A, B)), Types.pred(Types.SERIALIZABLE, A), Types.pred(Types.SERIALIZABLE, B))); + BINDING_CONSTANTS2.put(MMAP, new JavaConstructor("org/simantics/databoard/binding/impl/DefaultMapBinding", Types.NO_EFFECTS, Types.pred(Types.SERIALIZABLE, Types.apply(MMAP, A, B)), Types.pred(Types.SERIALIZABLE, A), Types.pred(Types.SERIALIZABLE, B))); } public static Reduction reduceSerializable(Type parameter) { diff --git a/bundles/org.simantics.scl.db/scl/Simantics/DB.scl b/bundles/org.simantics.scl.db/scl/Simantics/DB.scl index 023960678..74bc42204 100644 --- a/bundles/org.simantics.scl.db/scl/Simantics/DB.scl +++ b/bundles/org.simantics.scl.db/scl/Simantics/DB.scl @@ -11,31 +11,6 @@ effect WriteGraph "graph" "org.simantics.db.WriteGraph" -importJava "org.simantics.databoard.type.Datatype" where - data Datatype - @JavaName toString - showDatatype :: Datatype -> String - -instance Show Datatype where - show = showDatatype - -importJava "org.simantics.databoard.Bindings" where - @JavaName getBinding - datatypeBinding :: Datatype -> Binding Dynamic - -importJava "org.simantics.databoard.binding.mutable.Variant" where - @JavaName "" - createVariant_ :: Binding Dynamic -> Dynamic -> Variant - @JavaName "type" - variantDatatype :: Variant -> Datatype - -createVariant :: Datatype -> Dynamic -> Variant -createVariant dt v = createVariant_ (datatypeBinding dt) v - -importJava "org.simantics.databoard.Datatypes" where - @JavaName translate - translateDatatype :: String -> Datatype - importJava "org.simantics.db.Resource" where "A resource is a node in a semantic graph." data Resource diff --git a/bundles/org.simantics.scl.runtime/scl/Databoard.scl b/bundles/org.simantics.scl.runtime/scl/Databoard.scl new file mode 100644 index 000000000..f81376621 --- /dev/null +++ b/bundles/org.simantics.scl.runtime/scl/Databoard.scl @@ -0,0 +1,279 @@ +import "Prelude" +import "Random" + +/// Datatype /// + +"A data type component with component name and data type" +@JavaType "org.simantics.databoard.type.Component" +@FieldNames [name, "type"] +data DatatypeComponent = DatatypeComponent String Datatype + +"""A data type that represents the data types supported by the Simantics +Databoard plugin.""" +@JavaType "org.simantics.databoard.type.Datatype" +data Datatype = + @JavaType "org.simantics.databoard.type.BooleanType" + BooleanType + | @JavaType "org.simantics.databoard.type.ByteType" + ByteType + | @JavaType "org.simantics.databoard.type.IntegerType" + IntegerType + | @JavaType "org.simantics.databoard.type.LongType" + LongType + | @JavaType "org.simantics.databoard.type.FloatType" + FloatType + | @JavaType "org.simantics.databoard.type.DoubleType" + DoubleType + | @JavaType "org.simantics.databoard.type.StringType" + StringType + | @JavaType "org.simantics.databoard.type.ArrayType" + @FieldNames [componentType] + ArrayType Datatype + | @JavaType "org.simantics.databoard.type.OptionalType" + @FieldNames [componentType] + OptionalType Datatype + | @JavaType "org.simantics.databoard.type.MapType" + @FieldNames [keyType, valueType] + MapType Datatype Datatype + | @JavaType "org.simantics.databoard.type.RecordType" + @FieldNames [components] + RecordType (Vector DatatypeComponent) + | @JavaType "org.simantics.databoard.type.UntionType" + @FieldNames [components] + UnionType (Vector DatatypeComponent) + | @JavaType "org.simantics.databoard.type.VariantType" + VariantType + +importJava "org.simantics.databoard.type.Datatype" where + @private + @JavaName toString + showDatatype :: Datatype -> String + + "Get the number of type components in an data type" + @JavaName getComponentCount + datatypeCompnentCount :: Datatype -> Integer + + "Get a component type of a composite data type" + @JavaName getComponentType + datatypeComponentType :: Datatype -> ChildReference -> Datatype + + @private + @JavaName equals + datatypeEquals :: Datatype -> Datatype -> Boolean + +instance Show Datatype where + show = showDatatype + +instance Eq Datatype where + (==) = datatypeEquals + +/// Binding /// + +importJava "org.simantics.databoard.binding.Binding" where + "Check whether a dynamic object is an instance of a given binding" + @JavaName isInstance + isBindingInstance :: Binding Dynamic -> Dynamic -> Boolean + + "Create a serializable object from a textual representation" + parseValueDefinition :: Serializable a => String -> a + + "Compare two serializable objects\n\nResult is -1, 0 or 1 depending the partial ordering of the objects." + @JavaName compare + compareObjects :: Serializable a => a -> a -> Integer + + "Return true, if two serializable values are equal" + @JavaName equals + serializableEq :: Serializable a => a -> a -> Boolean + + "The default value of a serializable type" + @JavaName createDefault + serializableDefaultValue :: Serializable a => a + + "Create a random value of a serializable type" + @JavaName createRandom + serializableRandomValue :: Serializable a => a + + "Get a textual representation of a serializable value" + @JavaName toString + showSerializable :: Serializable a => a -> String + + @private + @JavaName getComponent + getSerializableComponent_ :: Serializable a => a -> ChildReference -> Binding b -> b + + "Get a component binding" + @JavaName getComponentBinding + getComponentBinding :: Binding a -> ChildReference -> Binding b + + @private + @JavaName equals + bindingEquals :: Binding a -> Binding a -> Boolean + +instance Eq (Binding a) where + (==) = bindingEquals + +"Get a child data component of a composite serializable value" +getSerializableComponent :: Serializable a => Serializable b => a -> ChildReference -> b +getSerializableComponent object ref = getSerializableComponent_ object ref binding + +/// Serializer /// + +importJava "org.simantics.databoard.serialization.Serializer" where + "A data serializer for SCL type a" + data Serializer a + + @private + @JavaName "serialize" + serialize_ :: Serializer a -> a -> ByteArray + + @private + @JavaName "deserialize" + deserialize_ :: Serializer a -> ByteArray -> a + +importJava "org.simantics.databoard.Bindings" where + @private + @JavaName "getSerializer" + serializerOf :: Binding a -> Serializer a + + @private + @JavaName toString + bindingToString :: Binding a -> String + + "Adapt between types using explicitly provided binding objects: `adapt_ value from to`" + @JavaName adapt + adapt_ :: a -> Binding a -> Binding b -> b + +"Adapt value from one serializable type to another" +adapt :: Serializable a => Serializable b => a -> b +adapt x = adapt_ x binding binding + +instance Show (Binding a) where + show = bindingToString + +"Serializes a value to a byte array using default serializer." +serialize :: Serializable a => a -> ByteArray +serialize v = serialize_ (serializerOf binding) v + +"Deserializes a value from a byte array using default serializer." +deserialize :: Serializable a => ByteArray -> a +deserialize ba = deserialize_ (serializerOf binding) ba + +importJava "org.simantics.databoard.Bindings" where + "Get a default binding for a given data type" + @JavaName getBinding + datatypeBinding :: Datatype -> Binding Dynamic + +importJava "org.simantics.databoard.Datatypes" where + "Get a data type from a string representation" + @JavaName translate + translateDatatype :: String -> Datatype + +importJava "org.simantics.databoard.binding.mutable.Variant" where + // data Variant (in Builtins) + "Create a variant using an explicitly provided binding value (unchecked cast)" + @JavaName "" + createVariant_ :: Binding Dynamic -> Dynamic -> Variant + + "Get the data type of a variant object" + @JavaName "type" + variantDatatype :: Variant -> Datatype + + "Get raw value contained by a variant (unchecked cast)" + @JavaName getValue + rawVariantValue :: Variant -> a + + "Create a variant from a raw object (based on Java class)" + @JavaName ofInstance + variantOf :: a -> Variant + + "Create a variant with explicitly provided binding and value" + @JavaName "" + variant_ :: Binding a -> a -> Variant + + "Get value from a variant using a given binding" + @JavaName getValue + variantValue_ :: Variant -> Binding a -> a + + @private + @JavaName toString + showVariant :: Variant -> String + + "Get a component of compound data value in a variant" + @JavaName getComponent + variantComponent :: Variant -> ChildReference -> Variant + +"Create a variant of a given data type from an object in the default binding (unchecked, use with extreme caution)" +createVariant :: Datatype -> Dynamic -> Variant +createVariant dt v = createVariant_ (datatypeBinding dt) v + +"Create a variant from a serializable value" +variant :: Serializable a => a -> Variant +variant v = variant_ binding v + +"Get the value of a variant in a serializable type" +variantValue :: Serializable a => Variant -> a +variantValue v = variantValue_ v binding + +instance Show Variant where + show = showVariant + +"Get an element of a compound variant value using an index reference" +variantElement :: Serializable a => Variant -> Integer -> a +variantElement v i = variantValue (variantComponent v (indexReference i)) + +importJava "org.simantics.databoard.accessor.reference.ChildReference" where + "A reference to a child element in a composite data type/binding or value" + data ChildReference + + "Combine a list of child data object references into a single path reference" + @JavaName compile + compileReference :: [ChildReference] -> ChildReference + +importJava "org.simantics.databoard.accessor.reference.IndexReference" where + """Get a reference to a child data object using an index (zero-based) +* Element index of an array object +* Field index of a record or union type +* 0: + * Key component of a map type/binding + * Component of any single-component type/binding (optional, array) + * Contained value/type of any single-element object (optional, union, variant) +* 1: + * Value component of a map type/binding + """ + @JavaName "" + indexReference :: Integer -> ChildReference + +importJava "org.simantics.databoard.accessor.reference.KeyReference" where + """Get a reference to a MapType child data object using a given key value +* Contained value of a map object for a given key value + """ + @JavaName "" + keyReference :: Variant -> ChildReference + +importJava "org.simantics.databoard.accessor.reference.NameReference" where + """Get a reference to a child data object using a field name +* A component name of a record or union data type/binding +* "key": The key component of a map data type/binding +* "value": The value component of a map data type/binding + """ + @JavaName "" + nameReference :: String -> ChildReference + +importJava "org.simantics.databoard.accessor.reference.LabelReference" where + """Get a reference to a child data object using a label +* A component name of a record or union data type/binding +* A string representation of the index of a record or union data type/binding component +* "v": The component type of an array/optional data type/binding +* "0"/"key": The key component of a map data type/binding +* "1"/"value": The value component of a map data type/binding + """ + @JavaName "" + labelReference :: String -> ChildReference + +importJava "org.simantics.databoard.accessor.reference.ComponentReference" where + """Get a reference to a component child data object +* Component of an array/optional data type/binding +* Contained value of an optional/variant/union object + """ + @JavaName "" + componentReference :: ChildReference diff --git a/bundles/org.simantics.scl.runtime/scl/Prelude.scl b/bundles/org.simantics.scl.runtime/scl/Prelude.scl index 4c20c99b5..6966b4489 100644 --- a/bundles/org.simantics.scl.runtime/scl/Prelude.scl +++ b/bundles/org.simantics.scl.runtime/scl/Prelude.scl @@ -558,6 +558,43 @@ importJava "java.lang.Math" where /// Integer /// +@private +importJava "java.lang.Byte" where + @JavaName toString + showByte :: Byte -> String + + @JavaName parseByte + readByte :: String -> Byte + +instance Eq Byte where + (==) = Java.bcmpeq + (!=) = Java.bcmpne + +instance Ord Byte where + (<) = Java.bcmplt + (<=) = Java.bcmple + (>) = Java.bcmpgt + (>=) = Java.bcmpge + +instance Additive Byte where + zero = Java.i2b Java.iconst_0 + (+) = Java.badd + +instance Ring Byte where + neg = Java.bneg + (-) = Java.bsub + one = Java.i2b Java.iconst_1 + (*) = Java.bmul + fromInteger = Java.i2b + +instance Show Byte where + show = showByte + precedence v = if v >= 0 then 0 else 100 + +instance Read Byte where + read = readByte + + @private importJava "java.lang.Short" where @JavaName toString @@ -2229,45 +2266,7 @@ instance Show TypeRep where isSpecialType (TCon "Builtin" "(,,,)") = True isSpecialType (TApply a _) = isSpecialType a */ -// Serializable - -importJava "org.simantics.databoard.serialization.Serializer" where - data Serializer a - - @private - @JavaName "serialize" - serialize_ :: Serializer a -> a -> ByteArray - - @private - @JavaName "deserialize" - deserialize_ :: Serializer a -> ByteArray -> a - -importJava "org.simantics.databoard.Bindings" where - @private - @JavaName "getSerializer" - serializerOf :: Binding a -> Serializer a - - @private - @JavaName toString - bindingToString :: Binding a -> String - - @JavaName adapt - adapt_ :: a -> Binding a -> Binding b -> b - -adapt :: Serializable a => Serializable b => a -> b -adapt x = adapt_ x binding binding - -instance Show (Binding a) where - show = bindingToString - -"Serializes a value to a byte array." -serialize :: Serializable a => a -> ByteArray -serialize v = serialize_ (serializerOf binding) v -"Deserializes a value from a byte array." -deserialize :: Serializable a => ByteArray -> a -deserialize ba = deserialize_ (serializerOf binding) ba - // ByteArray importJava "java.util.Arrays" where @@ -2278,56 +2277,6 @@ importJava "java.util.Arrays" where instance Show ByteArray where show = byteArrayToString -importJava "org.simantics.databoard.binding.mutable.Variant" where - // data Variant (in Builtins) - @JavaName getValue - rawVariantValue :: Variant -> a - @JavaName ofInstance - variantOf :: a -> Variant - @JavaName "" - variantOfWithBinding :: Binding a -> a -> Variant - @JavaName getValue - variantValue_ :: Variant -> Binding a -> a - @JavaName toString - showVariant :: Variant -> String - - @JavaName getComponent - variantComponent :: Variant -> ChildReference -> Variant - -variant :: Serializable a => a -> Variant -variant v = variantOfWithBinding binding v - -variantValue :: Serializable a => Variant -> a -variantValue v = variantValue_ v binding - -instance Show Variant where - show = showVariant - -variantElement :: Serializable a => Variant -> Integer -> a -variantElement v i = variantValue (variantComponent v (indexReference i)) - -importJava "org.simantics.databoard.accessor.reference.ChildReference" where - data ChildReference - - @JavaName compile - compileReference :: [ChildReference] -> ChildReference - -importJava "org.simantics.databoard.accessor.reference.IndexReference" where - @JavaName "" - indexReference :: Integer -> ChildReference - -importJava "org.simantics.databoard.accessor.reference.KeyReference" where - @JavaName "" - keyReference :: Variant -> ChildReference - -importJava "org.simantics.databoard.accessor.reference.NameReference" where - @JavaName "" - nameReference :: String -> ChildReference - -importJava "org.simantics.databoard.accessor.reference.LabelReference" where - @JavaName "" - labelReference :: String -> ChildReference - // Type @private diff --git a/bundles/org.simantics.scl.runtime/scl/StandardLibrary.scl b/bundles/org.simantics.scl.runtime/scl/StandardLibrary.scl index 76ecece9c..122fcd02b 100644 --- a/bundles/org.simantics.scl.runtime/scl/StandardLibrary.scl +++ b/bundles/org.simantics.scl.runtime/scl/StandardLibrary.scl @@ -4,6 +4,7 @@ include "BigInteger" include "ArrayList" as ArrayList include "String" as String include "Vector" +include "Databoard" include "Debug" as Debug include "Lazy" as Lazy include "File" as File -- 2.43.2