package scriptingLanguage.variables;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import scriptingLanguage.Interpreter;
import scriptingLanguage.Token;
import scriptingLanguage.errors.InterpreterException;
import scriptingLanguage.errors.InvalidAccessException;
import scriptingLanguage.errors.NullAccessException;
import scriptingLanguage.errors.VariableNotFoundException;
import scriptingLanguage.frames.AbstractFrame;
public class JavaMethod extends AbstractMethod<Method> {
private Object container;
public JavaMethod(JavaMethodClass type) {
super(type, null, null);
container = null;
}
public JavaMethod(JavaMethodClass type, Method method, Object container, AbstractFrame frame) {
super(type, method, frame);
this.container = container;
}
@Override
public int extend(AbstractClass<?> type) throws NullAccessException {
if (getType().equals(type))
return 0;
return getType().extend(type) + 1;
}
@Override
public Token eval(ArrayList<Token> args) throws ArrayIndexOutOfBoundsException, IllegalArgumentException, InterpreterException {
Object[] arguments = args.toArray();
try {
//Type checking is done by Java for this one
return ((JavaClass<?>) ((AbstractMethodClass) getType()).getReturnType()).eval(getSource().invoke(this.container instanceof Class<?> ? null : this.container, arguments));
}
catch (ClassCastException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new VariableNotFoundException(getDeclared().getInterpreter().evalFunctionName(getSource().getName(), args) + " is not defined in the current frame.");
}
}
@Override
public Token eval(AbstractClass<?> caller, Token parameters, AbstractFrame frame) throws ArrayIndexOutOfBoundsException, IllegalArgumentException, InterpreterException {
ArrayList<Token> args = Interpreter.evalFunctionArguments(caller, parameters, frame);
return eval(args);
}
@Override
public Variable<Method> clone() {
return new JavaMethod((JavaMethodClass) getType(), getSource(), container, getDeclared());
}
@Override
public void write(Variable<?> data) throws InvalidAccessException {
super.write(data);
JavaMethod newData = (JavaMethod) data;
container = newData.container;
}
}