--- /dev/null
+package org.simantics.scl.compiler.types;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
+import org.simantics.scl.compiler.internal.types.ast.TConAst;
+import org.simantics.scl.compiler.internal.types.ast.TypeAst;
+import org.simantics.scl.compiler.types.util.Polarity;
+import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
+
+public class TUnion extends Type {
+ public final Type[] effects;
+
+ public TUnion(Type ... effects) {
+ if(NULL_CHECKS) {
+ for(Type effect : effects)
+ if(effect == null)
+ throw new InternalCompilerError();
+ }
+ this.effects = effects;
+ }
+
+ @Override
+ public Type replace(TVar var, Type replacement) {
+ for(int i=0;i<effects.length;++i) {
+ Type effect = effects[i];
+ Type newEffect = effect.replace(var, replacement);
+ if(newEffect != effect) {
+ Type[] newEffects = new Type[effects.length];
+ for(int j=0;j<i;++j)
+ newEffects[j] = effects[j];
+ newEffects[i] = newEffect;
+ for(int j=i+1;j<effects.length;++j)
+ newEffects[j] = effects[j].replace(var, replacement);
+ return new TUnion(newEffects);
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public TypeAst toTypeAst(TypeUnparsingContext context) {
+ StringBuilder b = new StringBuilder();
+ //b.append("#");
+ for(int i=0;i<effects.length;++i) {
+ if(i > 0)
+ b.append(",");
+ b.append(effects[i].toString(context));
+ }
+ //b.append("#");
+ return new TConAst(b.toString());
+ }
+
+ @Override
+ public void toName(TypeUnparsingContext context, StringBuilder b) {
+ boolean first = true;
+ for(Type effect : effects) {
+ if(first)
+ first = false;
+ else
+ b.append('_');
+ effect.toName(context, b);
+ }
+ }
+
+ @Override
+ public void updateHashCode(TypeHashCodeContext context) {
+ context.append(TypeHashCodeContext.UNION);
+ for(Type effect : effects)
+ effect.updateHashCode(context);
+ }
+
+ @Override
+ public void collectFreeVars(ArrayList<TVar> vars) {
+ for(Type effect : effects)
+ effect.collectFreeVars(vars);
+ }
+
+ @Override
+ public void collectMetaVars(ArrayList<TMetaVar> vars) {
+ for(Type effect : effects)
+ effect.collectMetaVars(vars);
+ }
+
+ @Override
+ public void collectMetaVars(THashSet<TMetaVar> vars) {
+ for(Type effect : effects)
+ effect.collectMetaVars(vars);
+ }
+
+ @Override
+ public boolean isGround() {
+ for(Type effect : effects)
+ if(!effect.isGround())
+ return false;
+ return true;
+ }
+
+ @Override
+ public boolean containsMetaVars() {
+ for(Type effect : effects)
+ if(effect.containsMetaVars())
+ return true;
+ return false;
+ }
+
+ @Override
+ public int getClassId() {
+ return UNION_ID;
+ }
+
+ @Override
+ public boolean contains(TMetaVar other) {
+ for(Type type : effects)
+ if(type.contains(other))
+ return true;
+ return false;
+ }
+
+ @Override
+ public Type convertMetaVarsToVars() {
+ for(int i=0;i<effects.length;++i)
+ effects[i] = effects[i].convertMetaVarsToVars();
+ return this;
+ }
+
+ @Override
+ public boolean isMinimal() {
+ return effects.length == 0;
+ }
+
+ @Override
+ public boolean isMaximal() {
+ return false;
+ }
+
+ @Override
+ public void addPolarity(Polarity polarity) {
+ for(Type effect : effects)
+ effect.addPolarity(polarity);
+ }
+
+ @Override
+ public void collectEffectMetaVars(ArrayList<TMetaVar> vars) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void collectConcreteEffects(ArrayList<TCon> concreteEffects) {
+ for(Type effect : effects)
+ effect.collectConcreteEffects(concreteEffects);
+ }
+
+ @Override
+ public Type head() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
+ return Types.NO_EFFECTS;
+ }
+}