package php.runtime.reflection;
import php.runtime.Memory;
import php.runtime.common.LangMode;
import php.runtime.env.Context;
import php.runtime.env.DieException;
import php.runtime.env.Environment;
import php.runtime.exceptions.support.ErrorException;
import php.runtime.lang.BaseException;
import php.runtime.memory.ArrayMemory;
import php.runtime.reflection.helper.ClosureEntity;
import php.runtime.reflection.helper.GeneratorEntity;
import php.runtime.reflection.support.Entity;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
public class ModuleEntity extends Entity {
private int id;
private Class<?> nativeClazz;
protected Method nativeMethod;
private final Map<String, ClassEntity> classes;
private final List<FunctionEntity> functions;
private final Map<String, ConstantEntity> constants;
private final List<ClosureEntity> closures;
private final List<GeneratorEntity> generators;
protected boolean isLoaded;
private final static Memory[] argsMock = new Memory[]{};
public ModuleEntity(Context context) {
super(context);
this.classes = new LinkedHashMap<String, ClassEntity>();
this.functions = new ArrayList<FunctionEntity>();
this.constants = new LinkedHashMap<String, ConstantEntity>();
this.closures = new ArrayList<ClosureEntity>();
this.generators = new ArrayList<GeneratorEntity>();
this.setName(context.getModuleNameNoThrow());
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Method getNativeMethod() {
return nativeMethod;
}
public void setNativeMethod(Method nativeMethod) {
this.nativeMethod = nativeMethod;
}
public Memory include(Environment env, ArrayMemory locals) throws Throwable {
try {
return (Memory) nativeMethod.invoke(null, env, argsMock, locals);
} catch (InvocationTargetException e){
return env.__throwException(e);
}
}
public Memory include(Environment env) throws Throwable {
try {
return (Memory) nativeMethod.invoke(null, env, argsMock, env.getGlobals());
} catch (InvocationTargetException e){
return env.__throwException(e);
}
}
public Memory includeNoThrow(Environment env, ArrayMemory locals){
try {
return include(env, locals);
} catch (DieException e) {
throw e;
} catch (ErrorException e){
throw e;
} catch (BaseException e){
env.catchUncaught(e);
return Memory.NULL;
} catch (Exception e) {
env.catchUncaught(e);
return Memory.NULL;
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}
public Memory includeNoThrow(Environment env){
return includeNoThrow(env, env.getGlobals());
}
public boolean isLoaded() {
return isLoaded;
}
public void setLoaded(boolean loaded) {
isLoaded = loaded;
}
public Collection<ConstantEntity> getConstants(){
return constants.values();
}
public Collection<ClassEntity> getClasses(){
return classes.values();
}
public Collection<ClosureEntity> getClosures(){
return closures;
}
public Collection<GeneratorEntity> getGenerators() {
return generators;
}
public Collection<FunctionEntity> getFunctions(){
return functions;
}
public ClassEntity findClass(String name){
return classes.get(name.toLowerCase());
}
public FunctionEntity findFunction(int index){
if (index >= 0 && index < functions.size())
return functions.get(index);
else
return null;
}
public ConstantEntity findConstant(String name){
return constants.get(name.toLowerCase());
}
public ClosureEntity findClosure(int index){
if (index >= 0 && index < closures.size())
return closures.get(index);
else
return null;
}
public GeneratorEntity findGenerator(int index){
if (index >= 0 && index < generators.size())
return generators.get(index);
else
return null;
}
public void addConstant(ConstantEntity constant){
if (!constants.containsKey(constant.getName()))
constants.put(constant.getName(), constant);
}
public void addClosure(ClosureEntity closure){
closures.add(closure);
if (closure.getGeneratorEntity() != null) {
addGenerator(closure.getGeneratorEntity());
}
}
public void addGenerator(GeneratorEntity generator) {
generators.add(generator);
}
public void addClass(ClassEntity clazz){
classes.put(clazz.getLowerName(), clazz);
for (MethodEntity entity : clazz.getOwnedMethods()) {
if (entity.getGeneratorEntity() != null) {
addGenerator(entity.getGeneratorEntity());
}
}
}
public void addFunction(FunctionEntity function){
functions.add(function);
if (function.getGeneratorEntity() != null) {
addGenerator(function.getGeneratorEntity());
}
}
public Class<?> getNativeClazz() {
return nativeClazz;
}
public void setNativeClazz(Class<?> nativeClazz) {
this.nativeClazz = nativeClazz;
}
}