package org.simantics.scl.compiler.types; import java.util.ArrayList; 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.TVarAst; import org.simantics.scl.compiler.internal.types.ast.TypeAst; import org.simantics.scl.compiler.types.exceptions.KindUnificationException; import org.simantics.scl.compiler.types.kinds.KMetaVar; 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.map.hash.TObjectIntHashMap; import gnu.trove.set.hash.THashSet; public final class TVar extends Type { public static final TVar[] EMPTY_ARRAY = new TVar[0]; private Kind kind; TVar(Kind kind) { this.kind = kind; } public Kind getKind() { if(kind instanceof KMetaVar) kind = Kinds.canonical(kind); return kind; } @Override public Type replace(TVar var, Type replacement) { if(this == var) return replacement; else return this; } @Override public TypeAst toTypeAst(TypeUnparsingContext context) { return new TVarAst(context.getName(this)); } @Override public boolean equals(Object obj) { while(obj instanceof TMetaVar) { TMetaVar metaVar = (TMetaVar)obj; if(metaVar.ref == null) return false; else obj = metaVar.ref; } return this == obj; } @Override public void updateHashCode(TypeHashCodeContext context) { TObjectIntHashMap varHashCode = context.getVarHashCode(); if(varHashCode != null && varHashCode.containsKey(this)) context.append(varHashCode.get(this)); else context.append(System.identityHashCode(this)); } @Override public void collectFreeVars(ArrayList vars) { if(!vars.contains(this)) vars.add(this); } @Override public void collectMetaVars(ArrayList vars) { } @Override public void collectMetaVars(THashSet vars) { } @Override public void collectEffectMetaVars(ArrayList vars) { } @Override public boolean isGround() { return false; } public Kind inferKind(Environment context) throws KindUnificationException { if(kind == null) kind = Kinds.metaVar(); return kind; } @Override public boolean containsMetaVars() { return false; } @Override public void toName(TypeUnparsingContext context, StringBuilder b) { b.append(context.getName(this)); } @Override public int getClassId() { return VAR_ID; } @Override public boolean contains(TMetaVar other) { return false; } @Override public Type convertMetaVarsToVars() { return this; } @Override public void addPolarity(Polarity polarity) { } @Override public Type head() { return this; } @Override public Type copySkeleton(THashMap metaVarMap) { return this; } @Override public int hashCode() { return System.identityHashCode(this); } @Override public int hashCode(int hash) { return HashCodeUtils.update(hash, System.identityHashCode(this)); } @Override public int hashCode(int hash, TVar[] boundVars) { for(int i=0;i