--- /dev/null
+package org.simantics.scl.compiler.types.kinds;
+
+import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
+
+/**
+ * This is an abstract base class for type kinds. It has three child classes:
+ * KCon for constants, KArrow for kind arrows and KMetaVar for kind meta-variables.
+ *
+ * Child classes need to implement the method {@link #contains(KMetaVar)}, which
+ * returns true, if a given kind meta-variable points to this instance.
+ *
+ * The default implementation of {@link #toString()} is infinitely recursive, with
+ * {@link #toString(TypeUnparsingContext, StringBuilder)} and {@link #toStringPar(TypeUnparsingContext, StringBuilder)}
+ * both calling each other.
+ */
+public abstract class Kind {
+ public static final Kind[] EMPTY_ARRAY = new Kind[0];
+
+ @Override
+ public String toString() {
+ return toString(new TypeUnparsingContext());
+ }
+
+ public String toString(TypeUnparsingContext tuc) {
+ StringBuilder b = new StringBuilder();
+ toString(tuc, b);
+ return b.toString();
+ }
+
+ /**
+ * Write this kind to a string builder as an unparenthesized expression.
+ * If a subclass does not need parenthesis, it can implement the
+ * {@link #toStringPar(TypeUnparsingContext, StringBuilder)} method instead.
+ */
+ protected void toString(TypeUnparsingContext tuc, StringBuilder b) {
+ toStringPar(tuc, b);
+ }
+
+ /**
+ * Write this kind to a string builder as an atomic expression. The default implementation
+ * encloses the output of {@link #toString(TypeUnparsingContext, StringBuilder)} in parenthesis.
+ */
+ protected void toStringPar(TypeUnparsingContext tuc, StringBuilder b) {
+ b.append("(");
+ toString(tuc, b);
+ b.append(")");
+ }
+
+ /**
+ * Return true, if this kind has been unified with the given kind meta-variable.
+ */
+ public abstract boolean contains(KMetaVar var);
+}