]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/CallJava.java
Add support for dependency changes in SCL
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / constants / generic / CallJava.java
1 package org.simantics.scl.compiler.constants.generic;
2
3 import org.cojen.classfile.TypeDesc;
4 import org.simantics.scl.compiler.constants.FunctionValue;
5 import org.simantics.scl.compiler.internal.codegen.references.Val;
6 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
7 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
8 import org.simantics.scl.compiler.types.TVar;
9 import org.simantics.scl.compiler.types.Type;
10
11 /**
12  * This class represents a call to a Java method as an SCL function value.
13  * It is instantiated by the {@link org.simantics.scl.compiler.compilation.Elaboration.matchType(MethodRef, Type)} method. 
14  */
15 public class CallJava extends FunctionValue {
16     StackItem[] stackItems;
17     MethodRef methodRef;
18     OutputFilter filter;
19     
20     public CallJava(TVar[] typeParameters, Type effect, Type returnType,
21             Type[] parameterTypes, StackItem[] stackItems, MethodRef methodRef,
22             OutputFilter filter) {
23         super(typeParameters, effect, returnType, parameterTypes);
24         if(stackItems == null) {
25             stackItems = new StackItem[parameterTypes.length];
26             for(int i=0;i<parameterTypes.length;++i)
27                 stackItems[i] = new ParameterStackItem(i, parameterTypes[i]);
28         }
29         this.stackItems = stackItems;
30         this.methodRef = methodRef;
31         this.filter = filter;
32     }
33
34     @Override
35     public Type applyExact(MethodBuilder mb, Val[] parameters) {
36         methodRef.invoke(mb, stackItems, parameters);
37         if(filter != null)
38             filter.filter(mb);
39         return getReturnType();
40     }
41     
42     public MethodRef getMethodRef() {
43         return methodRef;
44     }
45     
46     @Override
47     public String toString() {
48         return methodRef.getName();
49     }
50
51     public final static int INCOMPARABLE = -2;
52     public final static int LESS = -1;
53     public final static int EQUAL = 0;
54     public final static int GREATER = 1;
55     
56     public int compareTo(JavaReferenceValidator validator, CallJava other) {
57         MethodRef m1 = methodRef;
58         MethodRef m2 = other.methodRef;
59         TypeDesc[] ps1 = m1.getParameterTypes();
60         TypeDesc[] ps2 = m2.getParameterTypes();
61         if(ps1.length != ps2.length)
62             return INCOMPARABLE;
63
64         boolean lessOrEqual = true;
65         boolean greaterOrEqual = true;
66         for(int i=0;i<ps1.length;++i) {
67             if(ps1[i].equals(ps2[i]))
68                 continue;
69             if(!validator.isAssignableFrom(ps1[i], ps2[i])) {
70                 lessOrEqual = false;
71             }
72             if(!validator.isAssignableFrom(ps2[i], ps1[i])) {
73                 greaterOrEqual = false;
74             }
75         }
76         if(lessOrEqual) {
77             if(greaterOrEqual)
78                 return EQUAL;
79             else
80                 return LESS;
81         }
82         else {
83             if(greaterOrEqual)
84                 return GREATER;
85             else
86                 return INCOMPARABLE;
87         }
88     }
89     
90     @Override
91     public void prepare(MethodBuilder mb) {
92         for(StackItem item : stackItems)
93             item.prepare(mb);
94     }
95 }