]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/types/JavaTypeTranslator.java
Merge "Re-enabled Acorn transaction cancellation support for testing"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / types / JavaTypeTranslator.java
1 package org.simantics.scl.compiler.internal.codegen.types;
2
3 import org.cojen.classfile.TypeDesc;
4 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
5 import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
6 import org.simantics.scl.compiler.elaboration.modules.TypeConstructor;
7 import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
8 import org.simantics.scl.compiler.environment.Environment;
9 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
10 import org.simantics.scl.compiler.types.TApply;
11 import org.simantics.scl.compiler.types.TCon;
12 import org.simantics.scl.compiler.types.TForAll;
13 import org.simantics.scl.compiler.types.TFun;
14 import org.simantics.scl.compiler.types.TMetaVar;
15 import org.simantics.scl.compiler.types.TPred;
16 import org.simantics.scl.compiler.types.TVar;
17 import org.simantics.scl.compiler.types.Type;
18 import org.simantics.scl.compiler.types.Types;
19 import org.simantics.scl.compiler.types.util.Typed;
20
21 public class JavaTypeTranslator {
22
23     Environment environment;
24     Type[] parameters = new Type[32];
25     
26     public JavaTypeTranslator(Environment environment) {
27         this.environment = environment;
28     }
29     
30     private void reverseParameters(int len) {
31         len >>= 1;
32         for(int i=0;i<len;++i) {
33             Type temp = parameters[i];
34             parameters[i] = parameters[len-i-1];
35             parameters[len-i-1] = temp;
36         }
37     }
38     
39     private TypeConstructor getTypeConstructor(TCon con) {
40         TypeDescriptor typeDescriptor = environment.getTypeDescriptor(con);
41         if(typeDescriptor == null)
42             throw new InternalCompilerError("Didn't find type constructor " + con.module + "/" + con.name + ".");
43         if(typeDescriptor instanceof TypeAlias)
44             throw new InternalCompilerError("Type " + con.module + "/" + con.name + " is a type alias.");
45         return (TypeConstructor)typeDescriptor;
46     }
47         
48     public TypeDesc toTypeDesc(Type type) {
49         while(true) {
50             if(type instanceof TCon)
51                 return getTypeConstructor((TCon)type).construct(this, Type.EMPTY_ARRAY);
52             else if(type instanceof TApply) {
53                 int i=0;
54                 while(true) {
55                     TApply apply = (TApply)type;
56                     parameters[i++] = Types.canonical(apply.parameter);
57                     type = Types.canonical(apply.function);
58                     if(type instanceof TCon) {
59                         reverseParameters(i);
60                         return getTypeConstructor((TCon)type).construct(this, parameters);
61                     }
62                     else if(type instanceof TApply)
63                         ;
64                     else if(type instanceof TVar)
65                         return TypeDesc.OBJECT;
66                     else
67                         break;
68                 }
69             }
70             else if(type instanceof TVar)
71                 return TypeDesc.OBJECT;
72             else if(type instanceof TFun) 
73                 return Constants.FUNCTION;
74             else if(type instanceof TForAll)
75                 type = ((TForAll)type).type;            
76             else if(type instanceof TPred) {
77                 TPred funcApply = (TPred)type;
78                 return environment.getTypeClass(funcApply.typeClass)
79                         .construct(this, funcApply.parameters);
80             }
81             else if(type instanceof TMetaVar) {
82                 TMetaVar metaVar = (TMetaVar)type;
83                 type = Types.canonical(metaVar);
84                 if(type instanceof TMetaVar)
85                     return TypeDesc.OBJECT;
86             }
87             else {
88                 throw new IllegalArgumentException("Invalid type " + type + ".");
89             }
90         }
91     }
92     
93     public TypeDesc getTypeDesc(Typed typed) {
94         return toTypeDesc(typed.getType());
95     }
96     
97     public TypeDesc[] toTypeDescs(Type[] types) {
98         TypeDesc[] result = new TypeDesc[types.length];
99         for(int i=0;i<types.length;++i)
100             result[i] = toTypeDesc(types[i]);
101         return result;
102     }
103     
104     public TypeDesc[] toTypeDescs(Type[] types, Type type) {
105         TypeDesc[] result = new TypeDesc[types.length+1];
106         for(int i=0;i<types.length;++i)
107             result[i] = toTypeDesc(types[i]);
108         result[types.length] = toTypeDesc(type);
109         return result;
110     }
111     
112     public TypeDesc[] getTypeDescs(Typed[] typeds) {
113         TypeDesc[] result = new TypeDesc[typeds.length];
114         for(int i=0;i<typeds.length;++i)
115             result[i] = getTypeDesc(typeds[i]);
116         return result;
117     }
118     
119     public static TypeDesc[] filterVoid(TypeDesc[] tds) {
120         int length = tds.length;
121         for(TypeDesc td : tds)
122             if(td.equals(TypeDesc.VOID))
123                 --length;
124         if(length == tds.length)
125             return tds;
126         TypeDesc[] result = new TypeDesc[length];
127         int j=0;
128         for(TypeDesc td : tds)
129             if(!td.equals(TypeDesc.VOID))
130                 result[j++] = td;
131         return result;
132     }
133     
134     public static TypeDesc toObjectType(TypeDesc td) {
135         if(td.equals(TypeDesc.VOID))
136             return Constants.TUPLE0;
137         else
138             return td.toObjectType();
139     }
140 }