Package scriptingLanguage.frames

Source Code of scriptingLanguage.frames.RootFrame

package scriptingLanguage.frames;

import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;

import scriptingLanguage.Interpreter;
import scriptingLanguage.Token;
import scriptingLanguage.errors.InterpreterException;
import scriptingLanguage.errors.UnexpectedTypeException;
import scriptingLanguage.frames.errors.FrameAccessException;
import scriptingLanguage.variables.AbstractClass;
import scriptingLanguage.variables.JavaClass;

public class RootFrame extends AbstractFrame {
  private final LinkedHashMap<String, AbstractClass<?>> types;
  private final LinkedHashMap<String, String> imports;
 
  public RootFrame(AbstractFrame previous, Interpreter interpreter) {
    super(previous, interpreter);
    types = new LinkedHashMap<>();
    imports = new LinkedHashMap<>();
  }
 
  public RootFrame(RootFrame base, RootFrame previous) {
    super(base, previous);
    types = new LinkedHashMap<>(base.types);
    imports = new LinkedHashMap<>(base.imports);
    variables = new LinkedHashMap<>(base.variables);
  }
 
  @Override
  public void addImport(String name) {
    int dot = name.lastIndexOf('.');
    if (name.charAt(dot + 1) == '*') {
      List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>();
      classLoadersList.add(ClasspathHelper.contextClassLoader());
      classLoadersList.add(ClasspathHelper.staticClassLoader());
     
      Reflections reflections = new Reflections(new ConfigurationBuilder().setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
          .setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0]))).filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix(name.substring(0, dot)))));
      Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);
      for (Class<?> clazz : classes) {
        name = clazz.getName();
        dot = name.lastIndexOf('.');
        imports.put(name.substring(dot + 1), name);
      }
    }
    else
      imports.put(name.substring(dot + 1), name);
  }
 
  @Override
  public String getImport(String name) throws FrameAccessException {
    return imports.containsKey(name) ? imports.get(name) : (previous != null ? previous.getImport(name) : name);
  }
 
  @Override
  protected AbstractClass<?> getType0(String type) throws UnexpectedTypeException, FrameAccessException {
    RootFrame frame = this;
    do {
      if (frame.types.containsKey(type))
        return frame.types.get(type);
      else if (frame.imports.containsKey(type) || frame.imports.containsValue(type)) {
        try {
          AbstractClass<?> output;
          frame.types.put(type, (output = new JavaClass<Object>(type, Class.forName(getImport(type)))));
          return output;
        }
        catch (ClassNotFoundException e) {
          e.printStackTrace();
        }
      }
    } while (frame.previous instanceof RootFrame && (frame = (RootFrame) frame.previous) != null);
    throw new UnexpectedTypeException(type + " is not a valid type.");
  }
 
  @Override
  protected boolean hasType0(String type) throws FrameAccessException {
    return types.containsKey(getImport(type)) || (previous != null && previous.hasType0(type));
  }
 
  @Override
  public Token makeNew(AbstractClass<?> caller, String type, Token parameters, AbstractFrame call) throws InterpreterException, ArrayIndexOutOfBoundsException {
    if (type.equals("Integer") || type.equals("String") || type.equals("Character") || type.equals("Double") || type.equals("Boolean") || type.equals("Complex") || type.equals("Long")
        || type.equals("Short") || type.equals("Byte"))
      return interpreter.eval(caller, parameters, call);
    AbstractClass<?> t = getType(type);
    return t.eval(caller, parameters, call);
  }
 
  @Override
  public boolean writeVariable(String variable, Token value, boolean isNew) throws InterpreterException {
    throw new FrameAccessException("Cannot write to a root frame after its creation.");
  }

  @Override
  public void addType(String name, AbstractClass<?> type) throws FrameAccessException {
    types.put(name, type);
  }
}
TOP

Related Classes of scriptingLanguage.frames.RootFrame

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.