--- /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.environment.Environment;
+import org.simantics.scl.compiler.internal.codegen.utils.NameMangling;
+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.exceptions.KindUnificationException;
+import org.simantics.scl.compiler.types.kinds.Kind;
+import org.simantics.scl.compiler.types.util.Polarity;
+import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
+
+/**
+ * This class represents an SCL type constant with a name given in a module.
+ */
+public class TCon extends Type {
+ public final String module;
+ public final String name;
+
+ TCon(String module, String name) {
+ if(NULL_CHECKS) {
+ if(module == null || name == null)
+ throw new NullPointerException();
+ }
+ this.module = module;
+ this.name = name;
+ }
+
+ @Override
+ public TCon replace(TVar var, Type replacement) {
+ // Constants don't include type variables
+ return this;
+ }
+
+ @Override
+ public TypeAst toTypeAst(TypeUnparsingContext context) {
+ if(module == Types.BUILTIN) {
+ char c = name.charAt(0);
+ if(Character.isLetter(c) || c == '(' || name.equals("[]"))
+ return new TConAst(name);
+ else
+ return new TConAst("(" + name + ")");
+ }
+ else
+ return new TConAst(name.length() <= 1 ? simplifiedModuleName(module) + "." + name : name);
+ }
+
+ private static String simplifiedModuleName(String name) {
+ int p = name.lastIndexOf('/');
+ if(p == -1)
+ return name;
+ else
+ return name.substring(p+1);
+ }
+
+ @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 int hashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public void updateHashCode(TypeHashCodeContext context) {
+ context.append(System.identityHashCode(this));
+ }
+
+ @Override
+ public void collectFreeVars(ArrayList<TVar> vars) {
+ }
+
+ @Override
+ public void collectMetaVars(ArrayList<TMetaVar> vars) {
+ }
+
+ @Override
+ public void collectMetaVars(THashSet<TMetaVar> vars) {
+ }
+
+ @Override
+ public void collectEffectMetaVars(ArrayList<TMetaVar> vars) {
+ }
+
+ @Override
+ public boolean isGround() {
+ return true;
+ }
+
+ public Kind inferKind(Environment context) throws KindUnificationException {
+ return context.getTypeConstructor(this).kind;
+ }
+
+ @Override
+ public boolean containsMetaVars() {
+ return false;
+ }
+
+ @Override
+ public void toName(TypeUnparsingContext context, StringBuilder b) {
+ b.append(NameMangling.mangle(name));
+ }
+
+ @Override
+ public int getClassId() {
+ return CON_ID;
+ }
+
+ @Override
+ public boolean contains(TMetaVar other) {
+ return false;
+ }
+
+ @Override
+ public Type convertMetaVarsToVars() {
+ return this;
+ }
+
+ @Override
+ public void addPolarity(Polarity polarity) {
+ }
+
+ @Override
+ public void collectConcreteEffects(ArrayList<TCon> concreteEffects) {
+ concreteEffects.add(this);
+ }
+
+ @Override
+ public Type head() {
+ return this;
+ }
+
+ @Override
+ public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
+ return this;
+ }
+}