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