--- /dev/null
+package org.simantics.scl.compiler.internal.codegen.types;
+
+import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
+import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.codegen.utils.Constants;
+import org.simantics.scl.compiler.types.TApply;
+import org.simantics.scl.compiler.types.TCon;
+import org.simantics.scl.compiler.types.TForAll;
+import org.simantics.scl.compiler.types.TFun;
+import org.simantics.scl.compiler.types.TMetaVar;
+import org.simantics.scl.compiler.types.TPred;
+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.util.Typed;
+
+public class JavaTypeTranslator {
+
+ Environment environment;
+ Type[] parameters = new Type[32];
+
+ public JavaTypeTranslator(Environment environment) {
+ this.environment = environment;
+ }
+
+ private void reverseParameters(int len) {
+ len >>= 1;
+ for(int i=0;i<len;++i) {
+ Type temp = parameters[i];
+ parameters[i] = parameters[len-i-1];
+ parameters[len-i-1] = temp;
+ }
+ }
+
+ public TypeDesc toTypeDesc(Type type) {
+ while(true) {
+ if(type instanceof TCon) {
+ TCon con = (TCon)type;
+ TypeConstructor typeConstructor = environment.getTypeConstructor(con);
+ if(typeConstructor == null)
+ throw new InternalCompilerError("Didn't find type constructor " + con.module + "/" + con.name + ".");
+ return typeConstructor.construct(this, Type.EMPTY_ARRAY);
+ }
+ else if(type instanceof TApply) {
+ int i=0;
+ while(true) {
+ TApply apply = (TApply)type;
+ parameters[i++] = Types.canonical(apply.parameter);
+ type = Types.canonical(apply.function);
+ if(type instanceof TCon) {
+ reverseParameters(i);
+ return environment.getTypeConstructor((TCon)type).construct(this, parameters);
+ }
+ else if(type instanceof TApply)
+ ;
+ else if(type instanceof TVar)
+ return TypeDesc.OBJECT;
+ else
+ break;
+ }
+ }
+ else if(type instanceof TVar)
+ return TypeDesc.OBJECT;
+ else if(type instanceof TFun)
+ return Constants.FUNCTION;
+ else if(type instanceof TForAll)
+ type = ((TForAll)type).type;
+ else if(type instanceof TPred) {
+ TPred funcApply = (TPred)type;
+ return environment.getTypeClass(funcApply.typeClass)
+ .construct(this, funcApply.parameters);
+ }
+ else if(type instanceof TMetaVar) {
+ TMetaVar metaVar = (TMetaVar)type;
+ type = Types.canonical(metaVar);
+ if(type instanceof TMetaVar)
+ return TypeDesc.OBJECT;
+ }
+ else {
+ throw new IllegalArgumentException("Invalid type " + type + ".");
+ }
+ }
+ }
+
+ public TypeDesc getTypeDesc(Typed typed) {
+ return toTypeDesc(typed.getType());
+ }
+
+ public TypeDesc[] toTypeDescs(Type[] types) {
+ TypeDesc[] result = new TypeDesc[types.length];
+ for(int i=0;i<types.length;++i)
+ result[i] = toTypeDesc(types[i]);
+ return result;
+ }
+
+ public TypeDesc[] toTypeDescs(Type[] types, Type type) {
+ TypeDesc[] result = new TypeDesc[types.length+1];
+ for(int i=0;i<types.length;++i)
+ result[i] = toTypeDesc(types[i]);
+ result[types.length] = toTypeDesc(type);
+ return result;
+ }
+
+ public TypeDesc[] getTypeDescs(Typed[] typeds) {
+ TypeDesc[] result = new TypeDesc[typeds.length];
+ for(int i=0;i<typeds.length;++i)
+ result[i] = getTypeDesc(typeds[i]);
+ return result;
+ }
+
+ public static TypeDesc[] filterVoid(TypeDesc[] tds) {
+ int length = tds.length;
+ for(TypeDesc td : tds)
+ if(td.equals(TypeDesc.VOID))
+ --length;
+ if(length == tds.length)
+ return tds;
+ TypeDesc[] result = new TypeDesc[length];
+ int j=0;
+ for(TypeDesc td : tds)
+ if(!td.equals(TypeDesc.VOID))
+ result[j++] = td;
+ return result;
+ }
+
+ public static TypeDesc toObjectType(TypeDesc td) {
+ if(td.equals(TypeDesc.VOID))
+ return Constants.TUPLE0;
+ else
+ return td.toObjectType();
+ }
+}