Package scriptingLanguage.variables

Source Code of scriptingLanguage.variables.JavaClass

package scriptingLanguage.variables;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

import scriptingLanguage.Interpreter;
import scriptingLanguage.Token;
import scriptingLanguage.Type;
import scriptingLanguage.errors.InterpreterException;
import scriptingLanguage.errors.VariableNotFoundException;
import scriptingLanguage.frames.AbstractFrame;

public class JavaClass<T> extends AbstractClass<Class<? extends T>> {
 
  public JavaClass(String name, Class<? extends T> source) {
    this(name, source, new Type<JavaClass<?>>(name));
  }
 
  public JavaClass(String name, Class<? extends T> source, Type<?> tokenType) {
    super(name, source, tokenType);
  }
 
  public Method getMethod(String name, AbstractClass<?>... parameters) throws VariableNotFoundException {
    for (Method method : getSource().getMethods()) {
      if (!method.getName().equals(name))
        continue;
      //TODO figure out how to get the closest match
      Class<?>[] parameterTypes = method.getParameterTypes();
      boolean matches = true;
      for (int i = 0; i < parameterTypes.length; i++) {
        if (!parameterTypes[i].isAssignableFrom(parameters[i].getClass())) {
          matches = false;
          break;
        }
      }
      if (matches)
        return method;
    }
    name = name + ":{";
    if (parameters.length > 0) {
      for (AbstractClass<?> clazz : parameters)
        name = name + clazz.getName() + ", ";
      name = name.substring(0, name.length() - 2);
    }
    throw new VariableNotFoundException("No methods that match " + name + "} exist in objects with the type, " + getSource().getName());
  }
 
  public Token eval(Object source) {
    return new Token(new JavaObject<>(this, (T) source), getTokenType());
  }
 
  @Override
  public Token eval(AbstractClass<?> caller, Token parameters, AbstractFrame frame) throws ArrayIndexOutOfBoundsException, IllegalArgumentException, InterpreterException {
    ArrayList<Token> params = Interpreter.evalFunctionArguments(caller, parameters, frame);
    AbstractClass<?>[] p = new AbstractClass<?>[params.size()];
    for (int i = 0; i < params.size(); i++)
      p[i] = ((Variable<?>) params.get(i).getCar()).getType();
    for (Constructor<?> constructor : getSource().getConstructors()) {
      //TODO figure out how to get the closest match
      Class<?>[] parameterTypes = constructor.getParameterTypes();
      boolean matches = true;
      for (int i = 0; i < parameterTypes.length; i++)
        if (!parameterTypes[i].isAssignableFrom((Class<?>) p[i].getSource())) {
          matches = false;
          break;
        }
      if (matches) {
        Object[] p2 = new Object[p.length];
        for (int i = 0; i < params.size(); i++)
          p2[i] = ((Variable<?>) params.get(i).getCar()).getSource();
        try {
          return new Token(new JavaObject<T>(this, (T) constructor.newInstance(p2)), getTokenType());
        }
        catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
          e.printStackTrace();
        }
      }
    }
    String name = getName() + ":{";
    if (p.length > 0) {
      for (AbstractClass<?> clazz : p)
        name = name + clazz.getName() + ", ";
      name = name.substring(0, name.length() - 2);
    }
    throw new VariableNotFoundException("No methods that match " + name + "} exist in objects with the type, " + getSource().getName());
  }
 
  @Override
  public boolean equals(Object o) {
    if (o instanceof JavaClass)
      return getSource().equals(((JavaClass<?>) o).getSource());
    return false;
  }
 
  @Override
  public int extend(AbstractClass<?> type) {
    if (!(type instanceof JavaClass) || !((JavaClass<?>) type).getSource().isAssignableFrom(getSource()))
      return -1;
    //Maybe some recursion through superclasses and interfaces?  Cross-check with the isAssignableFrom trick?
    return getSource().isAssignableFrom(((JavaClass<?>) type).getSource()) ? 1 : 0; //TODO figure out how do get distance
  }
 
  @Override
  public String getName() {
    return getSource().getName();
  }

  @Override
  public Variable<Class<? extends T>> clone() {
    return new JavaClass<T>(getName(), getSource(), getTokenType());
  }

  @Override
  public Token makePlaceholder() {
    return new Token(new JavaObject<T>(this, null), getTokenType());
  }
}
TOP

Related Classes of scriptingLanguage.variables.JavaClass

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.