package org.simantics.scl.compiler.types; import java.util.ArrayList; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.environment.Environment; import org.simantics.scl.compiler.internal.types.HashCodeUtils; 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.kinds.Kind; import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.Polarity; import org.simantics.scl.compiler.types.util.TypeUnparsingContext; import gnu.trove.map.hash.THashMap; import gnu.trove.set.hash.THashSet; 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 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 vars) { for(Type effect : effects) effect.collectFreeVars(vars); } @Override public void collectMetaVars(ArrayList vars) { for(Type effect : effects) effect.collectMetaVars(vars); } @Override public void collectMetaVars(THashSet 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 vars) { throw new UnsupportedOperationException(); } @Override public void collectConcreteEffects(ArrayList concreteEffects) { for(Type effect : effects) effect.collectConcreteEffects(concreteEffects); } @Override public Type head() { throw new UnsupportedOperationException(); } @Override public Type copySkeleton(THashMap metaVarMap) { return Types.NO_EFFECTS; } @Override public int hashCode(int hash) { int sum = UNION_HASH; for(Type effect : effects) sum += effect.hashCode(HashCodeUtils.SEED); return HashCodeUtils.updateWithPreprocessedValue(hash, sum); } @Override public int hashCode(int hash, TVar[] boundVars) { int sum = UNION_HASH; for(Type effect : effects) sum += effect.hashCode(HashCodeUtils.SEED, boundVars); return HashCodeUtils.updateWithPreprocessedValue(hash, sum); } @Override public int skeletonHashCode(int hash) { int sum = UNION_HASH; for(Type effect : effects) sum += effect.skeletonHashCode(HashCodeUtils.SEED); return HashCodeUtils.updateWithPreprocessedValue(hash, sum); } @Override public int skeletonHashCode(int hash, TVar[] boundVars) { int sum = UNION_HASH; for(Type effect : effects) sum += effect.skeletonHashCode(HashCodeUtils.SEED, boundVars); return HashCodeUtils.updateWithPreprocessedValue(hash, sum); } @Override public boolean equalsCanonical(Type other) { if(this == other) return true; if(!other.getClass().equals(TUnion.class)) return false; TUnion union = (TUnion)other; int length = effects.length; if(length != union.effects.length) return false; if(length == 0) return true; for(int i=0;i i) { effect = union.effects[i]; union.effects[i] = union.effects[j]; union.effects[j] = effect; } continue loop; } return false; } return true; } @Override public Kind getKind(Environment context) { return Kinds.EFFECT; } @Override public Type[] skeletonCanonicalChildren() { return EMPTY_ARRAY; } }