]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/JavaConstructor.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / constants / JavaConstructor.java
1 package org.simantics.scl.compiler.constants;
2
3 import java.util.Arrays;
4
5 import org.cojen.classfile.TypeDesc;
6 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
7 import org.simantics.scl.compiler.internal.codegen.references.Val;
8 import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
9 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
10 import org.simantics.scl.compiler.types.Type;
11 import org.simantics.scl.compiler.types.Types;
12
13 public class JavaConstructor extends FunctionValue {
14     
15     String className;
16     boolean hasStaticInstance = false;
17     
18     TypeDesc[] parameterTypeDescs;
19     
20     public JavaConstructor(String className, Type effect, Type returnType, Type ... parameterTypes) {
21         super(Types.freeVarsArray(Types.functionE(parameterTypes, 
22                 effect, returnType)), 
23                 effect, returnType, parameterTypes);
24         this.className = className;
25     }
26     
27     public JavaConstructor(String className, Type effect, TypeDesc[] parameterTypeDescs, 
28             Type returnType, Type ... parameterTypes) {
29         super(Types.freeVarsArray(Types.functionE(parameterTypes, 
30                 effect, returnType)),
31                 effect,
32                 returnType, parameterTypes);
33         this.className = className;
34         this.parameterTypeDescs = parameterTypeDescs;
35     }    
36     
37     @Override
38     public Type applyExact(MethodBuilder mb, Val[] parameters) {
39         if(parameterTypeDescs == null) {
40             JavaTypeTranslator tt = mb.getJavaTypeTranslator();
41             parameterTypeDescs = tt.toTypeDescs(parameterTypes);
42         }
43         
44         TypeDesc typeDesc = TypeDesc.forClass(className);
45         if(hasStaticInstance) {
46             mb.loadStaticField(typeDesc, "INSTANCE", typeDesc);
47         }
48         else {
49             mb.newObject(typeDesc);
50             mb.dup();
51             mb.push(parameters, parameterTypes);
52             mb.invokeConstructor(className, parameterTypeDescs);
53             // cb.checkCast(tt.toTypeDesc(returnType));
54         }
55         
56         return getReturnType();
57     }
58     
59     @Override
60     public String toString() {
61         return className + ".<init>";
62     }
63
64     public void setHasStaticInstance(boolean hasStaticInstance) {
65         if(parameterTypes.length > 0)
66             throw new InternalCompilerError();
67         this.hasStaticInstance = hasStaticInstance;
68     }
69
70     @Override
71     public int hashCode() {
72         final int prime = 31;
73         int result = 1;
74         result = prime * result
75                 + ((className == null) ? 0 : className.hashCode());
76         result = prime * result + (hasStaticInstance ? 1231 : 1237);
77         result = prime * result + Arrays.hashCode(parameterTypeDescs);
78         return result;
79     }
80
81     @Override
82     public boolean equals(Object obj) {
83         if (this == obj)
84             return true;
85         if (obj == null)
86             return false;
87         if (getClass() != obj.getClass())
88             return false;
89         JavaConstructor other = (JavaConstructor) obj;
90         if (className == null) {
91             if (other.className != null)
92                 return false;
93         } else if (!className.equals(other.className))
94             return false;
95         if (hasStaticInstance != other.hasStaticInstance)
96             return false;
97         if (!Arrays.equals(parameterTypeDescs, other.parameterTypeDescs))
98             return false;
99         return true;
100     }
101 }