1 package org.simantics.scl.compiler.types;
3 import java.util.ArrayList;
5 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
6 import org.simantics.scl.compiler.environment.Environment;
7 import org.simantics.scl.compiler.internal.types.HashCodeUtils;
8 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
9 import org.simantics.scl.compiler.internal.types.ast.TConAst;
10 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
11 import org.simantics.scl.compiler.types.kinds.Kind;
12 import org.simantics.scl.compiler.types.kinds.Kinds;
13 import org.simantics.scl.compiler.types.util.Polarity;
14 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
16 import gnu.trove.map.hash.THashMap;
17 import gnu.trove.set.hash.THashSet;
19 public class TUnion extends Type {
20 public final Type[] effects;
22 public TUnion(Type ... effects) {
24 for(Type effect : effects)
26 throw new InternalCompilerError();
28 this.effects = effects;
32 public Type replace(TVar var, Type replacement) {
33 for(int i=0;i<effects.length;++i) {
34 Type effect = effects[i];
35 Type newEffect = effect.replace(var, replacement);
36 if(newEffect != effect) {
37 Type[] newEffects = new Type[effects.length];
39 newEffects[j] = effects[j];
40 newEffects[i] = newEffect;
41 for(int j=i+1;j<effects.length;++j)
42 newEffects[j] = effects[j].replace(var, replacement);
43 return new TUnion(newEffects);
50 public TypeAst toTypeAst(TypeUnparsingContext context) {
51 StringBuilder b = new StringBuilder();
53 for(int i=0;i<effects.length;++i) {
56 b.append(effects[i].toString(context));
59 return new TConAst(b.toString());
63 public void toName(TypeUnparsingContext context, StringBuilder b) {
65 for(Type effect : effects) {
70 effect.toName(context, b);
75 public void updateHashCode(TypeHashCodeContext context) {
76 context.append(TypeHashCodeContext.UNION);
77 for(Type effect : effects)
78 effect.updateHashCode(context);
82 public void collectFreeVars(ArrayList<TVar> vars) {
83 for(Type effect : effects)
84 effect.collectFreeVars(vars);
88 public void collectMetaVars(ArrayList<TMetaVar> vars) {
89 for(Type effect : effects)
90 effect.collectMetaVars(vars);
94 public void collectMetaVars(THashSet<TMetaVar> vars) {
95 for(Type effect : effects)
96 effect.collectMetaVars(vars);
100 public boolean isGround() {
101 for(Type effect : effects)
102 if(!effect.isGround())
108 public boolean containsMetaVars() {
109 for(Type effect : effects)
110 if(effect.containsMetaVars())
116 public int getClassId() {
121 public boolean contains(TMetaVar other) {
122 for(Type type : effects)
123 if(type.contains(other))
129 public Type convertMetaVarsToVars() {
130 for(int i=0;i<effects.length;++i)
131 effects[i] = effects[i].convertMetaVarsToVars();
136 public boolean isMinimal() {
137 return effects.length == 0;
141 public boolean isMaximal() {
146 public void addPolarity(Polarity polarity) {
147 for(Type effect : effects)
148 effect.addPolarity(polarity);
152 public void collectEffectMetaVars(ArrayList<TMetaVar> vars) {
153 throw new UnsupportedOperationException();
157 public void collectConcreteEffects(ArrayList<TCon> concreteEffects) {
158 for(Type effect : effects)
159 effect.collectConcreteEffects(concreteEffects);
164 throw new UnsupportedOperationException();
168 public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
169 return Types.NO_EFFECTS;
173 public int hashCode(int hash) {
174 int sum = UNION_HASH;
175 for(Type effect : effects)
176 sum += effect.hashCode(HashCodeUtils.SEED);
177 return HashCodeUtils.updateWithPreprocessedValue(hash, sum);
181 public int hashCode(int hash, TVar[] boundVars) {
182 int sum = UNION_HASH;
183 for(Type effect : effects)
184 sum += effect.hashCode(HashCodeUtils.SEED, boundVars);
185 return HashCodeUtils.updateWithPreprocessedValue(hash, sum);
189 public boolean equalsCanonical(Type other) {
192 if(!other.getClass().equals(TUnion.class))
194 TUnion union = (TUnion)other;
195 int length = effects.length;
196 if(length != union.effects.length)
200 for(int i=0;i<length;++i) {
201 effects[i] = effects[i].canonical();
202 union.effects[i] = union.effects[i].canonical();
205 if(effects[0].equalsCanonical(union.effects[0]))
206 return effects[1].equalsCanonical(union.effects[1]);
208 return effects[0].equalsCanonical(union.effects[1]) &&
209 effects[1].equalsCanonical(union.effects[0]);
211 loop: for(int i=0;i<length;++i) {
212 Type effect = effects[i];
213 for(int j=i;j<length;++j)
214 if(effect.equalsCanonical(union.effects[j])) {
216 effect = union.effects[i];
217 union.effects[i] = union.effects[j];
218 union.effects[j] = effect;
228 public Kind getKind(Environment context) {