package org.simantics.scl.compiler.elaboration.modules; import java.util.ArrayList; import org.cojen.classfile.TypeDesc; import org.simantics.scl.compiler.common.datatypes.Constructor; import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator; import org.simantics.scl.compiler.types.TCon; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.KArrow; import org.simantics.scl.compiler.types.kinds.Kind; import org.simantics.scl.compiler.types.kinds.Kinds; public abstract class TypeConstructor extends TypeDescriptor { public Kind kind; public TVar[] parameters; public Type type; public Constructor[] constructors = Constructor.EMPTY_ARRAY; public String documentation; /** * A data type is open if it can be constructed without * constructors listed above. */ public boolean isOpen = true; public TypeConstructor(Kind kind) { super(null); this.kind = kind; } public TypeConstructor(TCon name, Kind kind) { super(name); this.kind = kind; ArrayList vars = new ArrayList(2); for(Kind cur = kind; cur instanceof KArrow;) { KArrow arrow = (KArrow)cur; vars.add(Types.var(arrow.domain)); cur = arrow.range; } this.parameters = vars.toArray(new TVar[vars.size()]); this.type = Types.apply(name, parameters); } public TypeConstructor(TCon name, TVar ... parameters) { super(name); setType(name, parameters); Kind kind = Kinds.STAR; for(int i = parameters.length-1;i>=0;--i) kind = Kinds.arrow(parameters[i].getKind(), kind); this.kind = kind; } public void setType(TCon name, TVar ... parameters) { this.name = name; this.parameters = parameters; this.type = Types.apply(name, parameters); } public void setConstructors(Constructor ... constructors) { this.constructors = constructors; } public abstract TypeDesc construct(JavaTypeTranslator translator, Type[] parameters); @Override public void setDocumentation(String documentation) { this.documentation = documentation; } @Override public Kind getKind() { return kind; } @Override public String getDocumentation() { return documentation; } }