+package org.simantics.scl.compiler.internal.elaboration.constraints;\r
+\r
+import org.cojen.classfile.TypeDesc;\r
+import org.simantics.scl.compiler.constants.ClassConstant;\r
+import org.simantics.scl.compiler.constants.Constant;\r
+import org.simantics.scl.compiler.constants.JavaConstructor;\r
+import org.simantics.scl.compiler.constants.JavaStaticField;\r
+import org.simantics.scl.compiler.constants.JavaStaticMethod;\r
+import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
+import org.simantics.scl.compiler.elaboration.expressions.EApplyType;\r
+import org.simantics.scl.compiler.elaboration.expressions.ELiteral;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
+import org.simantics.scl.compiler.elaboration.expressions.Expressions;\r
+import org.simantics.scl.compiler.types.TCon;\r
+import org.simantics.scl.compiler.types.TPred;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.kinds.Kinds;\r
+import org.simantics.scl.compiler.types.util.MultiApply;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+\r
+public class ReduceSerializable {\r
+ \r
+ private static final TVar A = Types.var(Kinds.STAR);\r
+ private static final TVar B = Types.var(Kinds.STAR);\r
+ \r
+ private static final Type SERIALIZABLE_BOOLEAN = Types.pred(Types.SERIALIZABLE, Types.BOOLEAN);\r
+ private static final Type SERIALIZABLE_BYTE = Types.pred(Types.SERIALIZABLE, Types.BYTE);\r
+ private static final Type SERIALIZABLE_INTEGER = Types.pred(Types.SERIALIZABLE, Types.INTEGER);\r
+ private static final Type SERIALIZABLE_LONG = Types.pred(Types.SERIALIZABLE, Types.LONG);\r
+ private static final Type SERIALIZABLE_FLOAT = Types.pred(Types.SERIALIZABLE, Types.FLOAT);\r
+ private static final Type SERIALIZABLE_DOUBLE = Types.pred(Types.SERIALIZABLE, Types.DOUBLE);\r
+ private static final Type SERIALIZABLE_STRING = Types.pred(Types.SERIALIZABLE, Types.STRING);\r
+ \r
+ private static final Type SERIALIZABLE_BOOLEAN_ARRAY = Types.pred(Types.SERIALIZABLE, Types.BOOLEAN_ARRAY);\r
+ private static final Type SERIALIZABLE_BYTE_ARRAY = Types.pred(Types.SERIALIZABLE, Types.BYTE_ARRAY);\r
+ private static final Type SERIALIZABLE_INTEGER_ARRAY = Types.pred(Types.SERIALIZABLE, Types.INTEGER_ARRAY);\r
+ private static final Type SERIALIZABLE_LONG_ARRAY = Types.pred(Types.SERIALIZABLE, Types.LONG_ARRAY);\r
+ private static final Type SERIALIZABLE_FLOAT_ARRAY = Types.pred(Types.SERIALIZABLE, Types.FLOAT_ARRAY);\r
+ private static final Type SERIALIZABLE_DOUBLE_ARRAY = Types.pred(Types.SERIALIZABLE, Types.DOUBLE_ARRAY);\r
+ \r
+ private static final Type SERIALIZABLE_BOOLEAN_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.BOOLEAN));\r
+ private static final Type SERIALIZABLE_BYTE_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.BYTE));\r
+ private static final Type SERIALIZABLE_INTEGER_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.INTEGER));\r
+ private static final Type SERIALIZABLE_LONG_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.LONG));\r
+ private static final Type SERIALIZABLE_FLOAT_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.FLOAT));\r
+ private static final Type SERIALIZABLE_DOUBLE_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.DOUBLE));\r
+ \r
+ private static final Type SERIALIZABLE_TUPLE0 = Types.pred(Types.SERIALIZABLE, Types.tuple());\r
+ private static final Type SERIALIZABLE_VARIANT = Types.pred(Types.SERIALIZABLE, Types.VARIANT);\r
+ \r
+ private static final TCon MLIST = Types.con("MList", "T");\r
+ private static final TCon MAP = Types.con("Map", "T");\r
+ private static final TCon MMAP = Types.con("MMap", "T");\r
+ \r
+ private static Constant GET_BINDING =\r
+ new JavaStaticMethod("org/simantics/databoard/Bindings", "getBinding", Types.NO_EFFECTS,\r
+ Types.pred(Types.SERIALIZABLE, A), Types.pred(Types.VEC_COMP, A));\r
+\r
+ private static final THashMap<TCon,Constant> BINDING_CONSTANTS0 = new THashMap<TCon,Constant>();\r
+ static {\r
+ BINDING_CONSTANTS0.put(Types.DOUBLE, new JavaStaticField("org/simantics/databoard/Bindings", "DOUBLE", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/DoubleBinding"), SERIALIZABLE_DOUBLE, -1));\r
+ BINDING_CONSTANTS0.put(Types.STRING, new JavaStaticField("org/simantics/databoard/Bindings", "STRING", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/StringBinding"), SERIALIZABLE_STRING, -1));\r
+ BINDING_CONSTANTS0.put(Types.INTEGER, new JavaStaticField("org/simantics/databoard/Bindings", "INTEGER", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/IntegerBinding"), SERIALIZABLE_INTEGER, -1));\r
+ BINDING_CONSTANTS0.put(Types.BOOLEAN, new JavaStaticField("org/simantics/databoard/Bindings", "BOOLEAN", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/BooleanBinding"), SERIALIZABLE_BOOLEAN, -1));\r
+ BINDING_CONSTANTS0.put(Types.BYTE, new JavaStaticField("org/simantics/databoard/Bindings", "BYTE", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ByteBinding"), SERIALIZABLE_BYTE, -1));\r
+ BINDING_CONSTANTS0.put(Types.FLOAT, new JavaStaticField("org/simantics/databoard/Bindings", "FLOAT", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/FloatBinding"), SERIALIZABLE_FLOAT, -1));\r
+ BINDING_CONSTANTS0.put(Types.LONG, new JavaStaticField("org/simantics/databoard/Bindings", "LONG", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/LongBinding"), SERIALIZABLE_LONG, -1));\r
+ BINDING_CONSTANTS0.put(Types.UNIT, new JavaStaticField("org/simantics/databoard/Bindings", "VOID", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/Binding"), SERIALIZABLE_TUPLE0, -1));\r
+ BINDING_CONSTANTS0.put(Types.VARIANT, new JavaStaticField("org/simantics/databoard/Bindings", "VARIANT", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/VariantBinding"), SERIALIZABLE_VARIANT, -1));\r
+ BINDING_CONSTANTS0.put(Types.DOUBLE_ARRAY, new JavaStaticField("org/simantics/databoard/Bindings", "DOUBLE_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_DOUBLE_ARRAY, -1));\r
+ BINDING_CONSTANTS0.put(Types.INTEGER_ARRAY, new JavaStaticField("org/simantics/databoard/Bindings", "INTEGER_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_INTEGER_ARRAY, -1));\r
+ BINDING_CONSTANTS0.put(Types.BOOLEAN_ARRAY, new JavaStaticField("org/simantics/databoard/Bindings", "BOOLEAN_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_BOOLEAN_ARRAY, -1));\r
+ BINDING_CONSTANTS0.put(Types.BYTE_ARRAY, new JavaStaticField("org/simantics/databoard/Bindings", "BYTE_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_BYTE_ARRAY, -1));\r
+ BINDING_CONSTANTS0.put(Types.FLOAT_ARRAY, new JavaStaticField("org/simantics/databoard/Bindings", "FLOAT_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_FLOAT_ARRAY, -1));\r
+ BINDING_CONSTANTS0.put(Types.LONG_ARRAY, new JavaStaticField("org/simantics/databoard/Bindings", "LONG_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_LONG_ARRAY, -1));\r
+ }\r
+ \r
+ private static final THashMap<TCon,Constant> BINDING_CONSTANTS1 = new THashMap<TCon,Constant>();\r
+ static {\r
+ BINDING_CONSTANTS1.put(Types.LIST, new JavaConstructor("org/simantics/databoard/binding/impl/ArrayListBinding", Types.NO_EFFECTS, Types.pred(Types.SERIALIZABLE, Types.list(A)), Types.pred(Types.SERIALIZABLE, A)));\r
+ BINDING_CONSTANTS1.put(Types.MAYBE, new JavaConstructor("org/simantics/databoard/binding/impl/OptionalBindingDefault", Types.NO_EFFECTS, Types.pred(Types.SERIALIZABLE, Types.apply(Types.MAYBE, A)), Types.pred(Types.SERIALIZABLE, A)));\r
+ BINDING_CONSTANTS1.put(Types.VECTOR, new JavaStaticMethod("org/simantics/databoard/Bindings", "getArrayBinding", Types.NO_EFFECTS, Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, A)), Types.pred(Types.SERIALIZABLE, A)));\r
+ BINDING_CONSTANTS1.put(MLIST, new JavaConstructor("org/simantics/databoard/binding/impl/ArrayListBinding", Types.NO_EFFECTS, Types.pred(Types.SERIALIZABLE, Types.apply(MLIST, A)), Types.pred(Types.SERIALIZABLE, A)));\r
+ }\r
+ \r
+ private static final THashMap<TCon,Constant> VECTOR_BINDING_CONSTANTS = new THashMap<TCon,Constant>();\r
+ static {\r
+ VECTOR_BINDING_CONSTANTS.put(Types.DOUBLE, new JavaStaticField("org/simantics/databoard/Bindings", "DOUBLE_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_DOUBLE_VECTOR, -1));\r
+ VECTOR_BINDING_CONSTANTS.put(Types.INTEGER, new JavaStaticField("org/simantics/databoard/Bindings", "INTEGER_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_INTEGER_VECTOR, -1));\r
+ VECTOR_BINDING_CONSTANTS.put(Types.BOOLEAN, new JavaStaticField("org/simantics/databoard/Bindings", "BOOLEAN_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_BOOLEAN_VECTOR, -1));\r
+ VECTOR_BINDING_CONSTANTS.put(Types.BYTE, new JavaStaticField("org/simantics/databoard/Bindings", "BYTE_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_BYTE_VECTOR, -1));\r
+ VECTOR_BINDING_CONSTANTS.put(Types.FLOAT, new JavaStaticField("org/simantics/databoard/Bindings", "FLOAT_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_FLOAT_VECTOR, -1));\r
+ VECTOR_BINDING_CONSTANTS.put(Types.LONG, new JavaStaticField("org/simantics/databoard/Bindings", "LONG_ARRAY", Types.NO_EFFECTS, TypeDesc.forClass("org/simantics/databoard/binding/ArrayBinding"), SERIALIZABLE_LONG_VECTOR, -1));\r
+ }\r
+ \r
+ private static final THashMap<TCon,Constant> BINDING_CONSTANTS2 = new THashMap<TCon,Constant>();\r
+ static {\r
+ 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)));\r
+ 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)));\r
+ }\r
+ \r
+ public static Reduction reduceSerializable(Type parameter) {\r
+ MultiApply apply = Types.matchApply(parameter);\r
+ if(!(apply.constructor instanceof TCon))\r
+ return null;\r
+ \r
+ switch(apply.parameters.length) {\r
+ case 0: {\r
+ Constant constant = BINDING_CONSTANTS0.get(apply.constructor);\r
+ if(constant != null)\r
+ return new Reduction(new ELiteral(constant), Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);\r
+ } break;\r
+ case 1: {\r
+ Type parameter0 = apply.parameters[0];\r
+ if(apply.constructor == Types.VECTOR) {\r
+ Constant vecConstant = VECTOR_BINDING_CONSTANTS.get(parameter0);\r
+ if(vecConstant != null)\r
+ return new Reduction(new ELiteral(vecConstant), Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);\r
+ }\r
+ Constant constant = BINDING_CONSTANTS1.get(apply.constructor);\r
+ if(constant != null)\r
+ return new Reduction(new EApplyType(new ELiteral(constant), parameter0), Type.EMPTY_ARRAY, new TPred[] { Types.pred(Types.SERIALIZABLE, parameter0) });\r
+ } break;\r
+ case 2: {\r
+ Constant constant = BINDING_CONSTANTS2.get(apply.constructor);\r
+ if(constant != null)\r
+ return new Reduction(Expressions.applyTypes(new ELiteral(constant), apply.parameters),\r
+ Type.EMPTY_ARRAY,\r
+ new TPred[] { Types.pred(Types.SERIALIZABLE, apply.parameters[0]), Types.pred(Types.SERIALIZABLE, apply.parameters[1]) });\r
+ } break;\r
+ }\r
+ \r
+ // Default to a binding based on the class of the type.\r
+ // This can be applied only if the type is ground type (i.e. does not contain type variables),\r
+ // because otherwise the Serializable instance could be provided as a parameter to the function\r
+ if(parameter.isGround()) {\r
+ Expression bindingGenerator = new EApplyType(new ELiteral(GET_BINDING), parameter);\r
+ Expression bindingExpression = new EApply(bindingGenerator, new ELiteral(new ClassConstant(Types.pred(Types.VEC_COMP, parameter), parameter)));\r
+ return new Reduction(bindingExpression, Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);\r
+ }\r
+ \r
+ return null;\r
+ }\r
+}\r