]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/Type.java
1709ebbeeeab415361894829982922bf8201bc13
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / types / Type.java
1 package org.simantics.scl.compiler.types;
2
3 import gnu.trove.map.hash.THashMap;
4 import gnu.trove.set.hash.THashSet;
5
6 import java.util.ArrayList;
7 import java.util.Map;
8
9 import org.simantics.scl.compiler.environment.Environment;
10 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
11 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
12 import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
13 import org.simantics.scl.compiler.types.kinds.KMetaVar;
14 import org.simantics.scl.compiler.types.kinds.Kind;
15 import org.simantics.scl.compiler.types.kinds.Kinds;
16 import org.simantics.scl.compiler.types.util.Polarity;
17 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
18
19
20
21 /**
22  * This class represents the types of variables and constants in SCL. 
23  * It is not meant to be extended outside of this package. 
24  * 
25  * @author Hannu Niemistö
26  */
27 public abstract class Type {
28     
29     public static final boolean NULL_CHECKS = true;
30     public static final Type[] EMPTY_ARRAY = new Type[0];
31     
32     public static final int FUN_ID = 0;
33     public static final int APPLY_ID = 1;
34     public static final int CON_ID = 2;
35     public static final int FORALL_ID = 3;
36     public static final int PRED_ID = 4;
37     public static final int METAVAR_ID = 5;
38     public static final int VAR_ID = 6;
39     public static final int UNION_ID = 7;
40     public static final int ALIAS_ID = 8;
41     
42     
43     /*
44      * This class is not meant to be extended outside of this package. 
45      */
46     Type() {        
47     }
48     
49     /**
50      * Recursively replace a type variable with a type in this type expression.
51      * @param var  A type variable to be replaced
52      * @param replacement  A the replacement type
53      * @return  A new type instance, or this, if no changes are necessary
54      */
55     public abstract Type replace(TVar var, Type replacement);
56     
57     public Type replace(TVar[] var, Type[] replacement) {
58         Type cur = this;
59         for(int i=0;i<var.length;++i)
60             cur = cur.replace(var[i], replacement[i]);
61         return cur;
62     }
63     
64     public <T extends Type> Type replace(THashMap<TVar, T> substitution) {
65         Type cur = this;
66         for(Map.Entry<TVar, T> entry : substitution.entrySet())
67             cur = cur.replace(entry.getKey(), entry.getValue());
68         return cur;
69     }
70     
71     abstract TypeAst toTypeAst(TypeUnparsingContext context);
72     
73     @Override
74     public String toString() {
75         return toString(new TypeUnparsingContext());
76     }
77     
78     public String toString(TypeUnparsingContext context) {
79         return toTypeAst(context).toString();
80     }
81     
82     public void toString(TypeUnparsingContext context, StringBuilder b) {
83         toTypeAst(context).toString(b);
84     }
85     
86     public void toString(TypeUnparsingContext context, StringBuilder b, int precedence) {
87         toTypeAst(context).toString(b, precedence);
88     }
89     
90     public String toName() {
91         TypeUnparsingContext context = new TypeUnparsingContext();
92         StringBuilder b = new StringBuilder();
93         toName(context, b);
94         return b.toString();
95     }
96     
97     public abstract void toName(TypeUnparsingContext context, StringBuilder b);
98
99     @Override
100     public boolean equals(Object obj) {
101         if(this == obj)
102             return true;
103         if(obj == null || !(obj instanceof Type))
104             return false;
105         return Types.equals(this, (Type)obj);
106     }
107     
108     @Override
109     public int hashCode() {
110         TypeHashCodeContext context = new TypeHashCodeContext();
111         updateHashCode(context);
112         return context.getResult();
113     }
114     
115     public abstract void updateHashCode(TypeHashCodeContext context);
116
117     public abstract void collectFreeVars(ArrayList<TVar> vars);
118     
119     public abstract void collectMetaVars(ArrayList<TMetaVar> vars);
120     public abstract void collectMetaVars(THashSet<TMetaVar> vars);
121     public abstract void collectEffectMetaVars(ArrayList<TMetaVar> vars);
122
123     public abstract boolean contains(TMetaVar other);
124
125     public abstract Type convertMetaVarsToVars();
126     
127     public abstract boolean isGround();
128
129         public Kind inferKind(Environment context) throws KindUnificationException {
130         KMetaVar var = Kinds.metaVar();
131         checkKind(context, var);
132         return Kinds.canonical(var);
133     }
134
135         public void checkKind(Environment context, Kind requiredKind) throws KindUnificationException {
136         Kind kind = inferKind(context);
137         Kinds.unify(kind, requiredKind);
138     }
139         
140         public abstract boolean containsMetaVars();
141         
142         public abstract int getClassId();
143         
144     public boolean isMinimal() {
145         return true;
146     }
147     
148     public boolean isMaximal() {
149         return true;
150     }
151
152     public abstract void addPolarity(Polarity polarity);
153
154     public void collectConcreteEffects(ArrayList<TCon> concreteEffects) {
155     }
156     
157     public abstract Type head();
158     
159     /**
160      * Creates an independent copy of the type, but replaces all effects by metavars
161      */
162     public abstract Type copySkeleton(THashMap<TMetaVar,TMetaVar> metaVarMap);
163
164 }