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 + "."; } 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; } }