--- /dev/null
+package org.simantics.scl.compiler.constants;
+
+import java.util.Arrays;
+
+import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.internal.codegen.references.Val;
+import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+
+public class JavaConstructor extends FunctionValue {
+
+ String className;
+ boolean hasStaticInstance = false;
+
+ TypeDesc[] parameterTypeDescs;
+
+ public JavaConstructor(String className, Type effect, Type returnType, Type ... parameterTypes) {
+ super(Types.freeVarsArray(Types.functionE(parameterTypes,
+ effect, returnType)),
+ effect, returnType, parameterTypes);
+ this.className = className;
+ }
+
+ public JavaConstructor(String className, Type effect, TypeDesc[] parameterTypeDescs,
+ Type returnType, Type ... parameterTypes) {
+ super(Types.freeVarsArray(Types.functionE(parameterTypes,
+ effect, returnType)),
+ effect,
+ returnType, parameterTypes);
+ this.className = className;
+ this.parameterTypeDescs = parameterTypeDescs;
+ }
+
+ @Override
+ public Type applyExact(MethodBuilder mb, Val[] parameters) {
+ if(parameterTypeDescs == null) {
+ JavaTypeTranslator tt = mb.getJavaTypeTranslator();
+ parameterTypeDescs = tt.toTypeDescs(parameterTypes);
+ }
+
+ TypeDesc typeDesc = TypeDesc.forClass(className);
+ if(hasStaticInstance) {
+ mb.loadStaticField(typeDesc, "INSTANCE", typeDesc);
+ }
+ else {
+ mb.newObject(typeDesc);
+ mb.dup();
+ mb.push(parameters, parameterTypes);
+ mb.invokeConstructor(className, parameterTypeDescs);
+ // cb.checkCast(tt.toTypeDesc(returnType));
+ }
+
+ return getReturnType();
+ }
+
+ @Override
+ public String toString() {
+ return className + ".<init>";
+ }
+
+ public void setHasStaticInstance(boolean hasStaticInstance) {
+ if(parameterTypes.length > 0)
+ throw new InternalCompilerError();
+ this.hasStaticInstance = hasStaticInstance;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((className == null) ? 0 : className.hashCode());
+ result = prime * result + (hasStaticInstance ? 1231 : 1237);
+ result = prime * result + Arrays.hashCode(parameterTypeDescs);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ JavaConstructor other = (JavaConstructor) obj;
+ if (className == null) {
+ if (other.className != null)
+ return false;
+ } else if (!className.equals(other.className))
+ return false;
+ if (hasStaticInstance != other.hasStaticInstance)
+ return false;
+ if (!Arrays.equals(parameterTypeDescs, other.parameterTypeDescs))
+ return false;
+ return true;
+ }
+}