1 package org.simantics.scl.compiler.internal.elaboration.constraints;
\r
3 import org.cojen.classfile.TypeDesc;
\r
4 import org.simantics.scl.compiler.constants.ClassConstant;
\r
5 import org.simantics.scl.compiler.constants.Constant;
\r
6 import org.simantics.scl.compiler.constants.JavaConstructor;
\r
7 import org.simantics.scl.compiler.constants.JavaStaticField;
\r
8 import org.simantics.scl.compiler.constants.JavaStaticMethod;
\r
9 import org.simantics.scl.compiler.elaboration.expressions.EApply;
\r
10 import org.simantics.scl.compiler.elaboration.expressions.EApplyType;
\r
11 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
\r
12 import org.simantics.scl.compiler.elaboration.expressions.Expression;
\r
13 import org.simantics.scl.compiler.elaboration.expressions.Expressions;
\r
14 import org.simantics.scl.compiler.types.TCon;
\r
15 import org.simantics.scl.compiler.types.TPred;
\r
16 import org.simantics.scl.compiler.types.TVar;
\r
17 import org.simantics.scl.compiler.types.Type;
\r
18 import org.simantics.scl.compiler.types.Types;
\r
19 import org.simantics.scl.compiler.types.kinds.Kinds;
\r
20 import org.simantics.scl.compiler.types.util.MultiApply;
\r
22 import gnu.trove.map.hash.THashMap;
\r
24 public class ReduceSerializable {
\r
26 private static final TVar A = Types.var(Kinds.STAR);
\r
27 private static final TVar B = Types.var(Kinds.STAR);
\r
29 private static final Type SERIALIZABLE_BOOLEAN = Types.pred(Types.SERIALIZABLE, Types.BOOLEAN);
\r
30 private static final Type SERIALIZABLE_BYTE = Types.pred(Types.SERIALIZABLE, Types.BYTE);
\r
31 private static final Type SERIALIZABLE_INTEGER = Types.pred(Types.SERIALIZABLE, Types.INTEGER);
\r
32 private static final Type SERIALIZABLE_LONG = Types.pred(Types.SERIALIZABLE, Types.LONG);
\r
33 private static final Type SERIALIZABLE_FLOAT = Types.pred(Types.SERIALIZABLE, Types.FLOAT);
\r
34 private static final Type SERIALIZABLE_DOUBLE = Types.pred(Types.SERIALIZABLE, Types.DOUBLE);
\r
35 private static final Type SERIALIZABLE_STRING = Types.pred(Types.SERIALIZABLE, Types.STRING);
\r
37 private static final Type SERIALIZABLE_BOOLEAN_ARRAY = Types.pred(Types.SERIALIZABLE, Types.BOOLEAN_ARRAY);
\r
38 private static final Type SERIALIZABLE_BYTE_ARRAY = Types.pred(Types.SERIALIZABLE, Types.BYTE_ARRAY);
\r
39 private static final Type SERIALIZABLE_INTEGER_ARRAY = Types.pred(Types.SERIALIZABLE, Types.INTEGER_ARRAY);
\r
40 private static final Type SERIALIZABLE_LONG_ARRAY = Types.pred(Types.SERIALIZABLE, Types.LONG_ARRAY);
\r
41 private static final Type SERIALIZABLE_FLOAT_ARRAY = Types.pred(Types.SERIALIZABLE, Types.FLOAT_ARRAY);
\r
42 private static final Type SERIALIZABLE_DOUBLE_ARRAY = Types.pred(Types.SERIALIZABLE, Types.DOUBLE_ARRAY);
\r
44 private static final Type SERIALIZABLE_BOOLEAN_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.BOOLEAN));
\r
45 private static final Type SERIALIZABLE_BYTE_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.BYTE));
\r
46 private static final Type SERIALIZABLE_INTEGER_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.INTEGER));
\r
47 private static final Type SERIALIZABLE_LONG_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.LONG));
\r
48 private static final Type SERIALIZABLE_FLOAT_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.FLOAT));
\r
49 private static final Type SERIALIZABLE_DOUBLE_VECTOR = Types.pred(Types.SERIALIZABLE, Types.pred(Types.VECTOR, Types.DOUBLE));
\r
51 private static final Type SERIALIZABLE_TUPLE0 = Types.pred(Types.SERIALIZABLE, Types.tuple());
\r
52 private static final Type SERIALIZABLE_VARIANT = Types.pred(Types.SERIALIZABLE, Types.VARIANT);
\r
54 private static final TCon MLIST = Types.con("MList", "T");
\r
55 private static final TCon MAP = Types.con("Map", "T");
\r
56 private static final TCon MMAP = Types.con("MMap", "T");
\r
58 private static Constant GET_BINDING =
\r
59 new JavaStaticMethod("org/simantics/databoard/Bindings", "getBinding", Types.NO_EFFECTS,
\r
60 Types.pred(Types.SERIALIZABLE, A), Types.pred(Types.VEC_COMP, A));
\r
62 private static final THashMap<TCon,Constant> BINDING_CONSTANTS0 = new THashMap<TCon,Constant>();
\r
64 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
65 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
66 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
67 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
68 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
69 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
70 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
71 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
72 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
73 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
74 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
75 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
76 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
77 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
78 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
81 private static final THashMap<TCon,Constant> BINDING_CONSTANTS1 = new THashMap<TCon,Constant>();
\r
83 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
84 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
85 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
86 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
89 private static final THashMap<TCon,Constant> VECTOR_BINDING_CONSTANTS = new THashMap<TCon,Constant>();
\r
91 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
92 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
93 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
94 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
95 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
96 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
99 private static final THashMap<TCon,Constant> BINDING_CONSTANTS2 = new THashMap<TCon,Constant>();
\r
101 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
102 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
105 public static Reduction reduceSerializable(Type parameter) {
\r
106 MultiApply apply = Types.matchApply(parameter);
\r
107 if(!(apply.constructor instanceof TCon))
\r
110 switch(apply.parameters.length) {
\r
112 Constant constant = BINDING_CONSTANTS0.get(apply.constructor);
\r
113 if(constant != null)
\r
114 return new Reduction(new ELiteral(constant), Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
\r
117 Type parameter0 = apply.parameters[0];
\r
118 if(apply.constructor == Types.VECTOR) {
\r
119 Constant vecConstant = VECTOR_BINDING_CONSTANTS.get(parameter0);
\r
120 if(vecConstant != null)
\r
121 return new Reduction(new ELiteral(vecConstant), Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
\r
123 Constant constant = BINDING_CONSTANTS1.get(apply.constructor);
\r
124 if(constant != null)
\r
125 return new Reduction(new EApplyType(new ELiteral(constant), parameter0), Type.EMPTY_ARRAY, new TPred[] { Types.pred(Types.SERIALIZABLE, parameter0) });
\r
128 Constant constant = BINDING_CONSTANTS2.get(apply.constructor);
\r
129 if(constant != null)
\r
130 return new Reduction(Expressions.applyTypes(new ELiteral(constant), apply.parameters),
\r
132 new TPred[] { Types.pred(Types.SERIALIZABLE, apply.parameters[0]), Types.pred(Types.SERIALIZABLE, apply.parameters[1]) });
\r
136 // Default to a binding based on the class of the type.
\r
137 // This can be applied only if the type is ground type (i.e. does not contain type variables),
\r
138 // because otherwise the Serializable instance could be provided as a parameter to the function
\r
139 if(parameter.isGround()) {
\r
140 Expression bindingGenerator = new EApplyType(new ELiteral(GET_BINDING), parameter);
\r
141 Expression bindingExpression = new EApply(bindingGenerator, new ELiteral(new ClassConstant(Types.pred(Types.VEC_COMP, parameter), parameter)));
\r
142 return new Reduction(bindingExpression, Type.EMPTY_ARRAY, TPred.EMPTY_ARRAY);
\r