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.ClassBuilder; import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder; import org.simantics.scl.compiler.top.SCLCompilerConfiguration; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; public class JavaMethod extends FunctionValue { String className; String methodName; TypeDesc returnTypeDesc; TypeDesc[] parameterTypeDescs; boolean virtual; public JavaMethod(boolean virtual, String className, String methodName, Type effect, TypeDesc returnTypeDesc, TypeDesc[] parameterTypeDescs, Type returnType, Type ... parameterTypes) { super(Types.freeVarsArray( Types.functionE(parameterTypes, effect, returnType)), effect, returnType, parameterTypes); if(SCLCompilerConfiguration.DEBUG) { if(className == null) throw new NullPointerException(); if(methodName == null) throw new NullPointerException(); if(parameterTypeDescs != null) for(TypeDesc td : parameterTypeDescs) if(td.equals(TypeDesc.VOID)) throw new InternalCompilerError(); } ClassBuilder.checkClassName(className); this.virtual = virtual; this.className = className; this.methodName = methodName; this.returnTypeDesc = returnTypeDesc; this.parameterTypeDescs = parameterTypeDescs; } public JavaMethod(boolean virtual, String className, String methodName, Type effect, Type returnType, Type ... parameterTypes) { this(virtual, className, methodName, effect, null, null, returnType, parameterTypes); } @Override public Type applyExact(MethodBuilder mb, Val[] parameters) { if(returnTypeDesc == null) { JavaTypeTranslator tt = mb.getJavaTypeTranslator(); returnTypeDesc = tt.toTypeDesc(returnType); parameterTypeDescs = JavaTypeTranslator.filterVoid( tt.toTypeDescs(Arrays.copyOfRange(parameterTypes, 1, parameterTypes.length))); } mb.push(parameters, parameterTypes); if(virtual) mb.invokeVirtual(className, methodName, returnTypeDesc, parameterTypeDescs); else mb.invokeInterface(className, methodName, returnTypeDesc, parameterTypeDescs); return getReturnType(); } @Override public String toString() { return className + "." + methodName; } }