/*
* $Id: CompiledScope.java,v 1.7 2002/09/16 08:05:04 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.script.compiler;
import anvil.core.Any;
import anvil.core.runtime.AnyFunction;
import anvil.core.runtime.AnyType;
import anvil.doc.Doc;
import anvil.script.Context;
import anvil.script.Type;
import anvil.script.Scope;
import anvil.script.ClassType;
import anvil.script.Function;
import anvil.script.CompilableFunction;
import anvil.script.InterfaceType;
import anvil.script.MethodType;
import anvil.script.ConstantVariableType;
import anvil.script.MemberVariableType;
import anvil.script.StaticVariableType;
import anvil.java.util.Hashlist;
import anvil.java.util.BindingEnumeration;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.util.Enumeration;
/**
* class Compiled
*
* @author: Jani Lehtim�ki
*/
public abstract class CompiledScope extends Compiled implements Scope
{
protected Hashlist _types = new Hashlist();
protected Class _class = null;
protected String _descriptor = null;
public CompiledScope(Scope parent, Class clazz, String name, Doc document)
{
super(parent, name, document);
if (clazz == null) {
clazz = this.getClass();
}
_class = clazz;
_descriptor = clazz.getName().replace('.', '/');
}
protected void initializeMembers(ClassLoader classloader)
{
try {
Method[] methods = _class.getDeclaredMethods();
Constructor[] constructors = _class.getConstructors();
Class[] classes = _class.getDeclaredClasses();
Object[] members = (Object[])getstatic(_class, "_members");
int n = members.length;
for(int i=0; i<n; i+=4) {
if (members[i] == null) {
break;
}
int type = ((Integer)members[i]).intValue();
String name = (String)members[i+1];
Doc doc = (Doc)members[i+2];
Object data = members[i+3];
switch(type) {
case Type.MODULE:
{
onScript(name, doc);
}
break;
case NAMESPACE:
{
Class innercls = findNamespace(classes, name);
onNamespace(classloader, innercls, name, doc);
}
break;
case CLASS:
{
Class innercls = findClass(classes, name);
onClass(classloader, innercls, name, doc);
}
break;
case INTERFACE:
{
Class innercls = findInterface(classes, name);
onInterface(classloader, innercls, name, doc);
}
break;
case FUNCTION:
{
Object[] parameters = (Object[])data;
Method method = findMethod(methods, "f_" + name);
onFunction(method, name, parameters, doc);
}
break;
case METHOD:
{
Method method = findMethod(methods, "m_" + name);
Object[] parameters = (Object[])data;
onMethod(method, name, parameters, doc);
}
break;
case INTERFACE_METHOD:
{
Method method = findMethod(methods, "m_" + name);
Object[] parameters = (Object[])data;
onInterfaceMethod(method, name, parameters, doc);
}
break;
case CONSTRUCTOR:
{
Method method = findMethod(methods, "m_" + name);
Object[] parameters = (Object[])data;
Constructor constructor = null;
int lastlength = -1;
for(int j=0; j<constructors.length; j++) {
Class[] types = constructors[j].getParameterTypes();
if (types.length > lastlength) {
constructor = constructors[j];
lastlength = types.length;
}
}
onConstructor(method, constructor, name, parameters, doc);
}
break;
case CONSTANT_VARIABLE:
{
Field field = _class.getDeclaredField("c_" + name);
onConstantVariable(field, name, doc);
}
break;
case STATIC_VARIABLE:
{
Field field = _class.getDeclaredField("s_" + name);
onStaticVariable(field, name, doc);
}
break;
case MEMBER_VARIABLE:
{
Field field = _class.getDeclaredField("f_" + name);
onMemberVariable(field, name, doc);
}
break;
default:
{
anvil.Log.log().error("Invalid member code "+type+" for '"+name+"' at initialization of "+_class.getName());
}
break;
}
}
} catch (Throwable t) {
anvil.Log.log().error("Initialization of "+_class.getName()+" failed", t);
}
}
protected void onScript(String name, Doc doc)
{
}
protected Scope onNamespace(ClassLoader classloader, Class cls, String name, Doc doc)
{
Scope namespace = new CompiledNamespace(classloader, this, cls, name, doc);
declare(namespace);
return namespace;
}
protected ClassType onClass(ClassLoader classloader, Class cls, String name, Doc doc)
{
ClassType clazz = new CompiledClassType(classloader, this, cls, name, doc);
declare(clazz);
return clazz;
}
protected InterfaceType onInterface(ClassLoader classloader, Class cls, String name, Doc doc)
{
InterfaceType intrface = new CompiledInterfaceType(classloader, this, cls, name, doc);
declare(intrface);
return intrface;
}
protected CompilableFunction onFunction(Method method, String name, Object[] parameters, Doc doc)
{
CompilableFunction function = new FunctionBase(this, method, name, parameters, doc);
putstatic(_class, "f_" + name, function);
putstatic(_class, "F_" + name, new AnyFunction(function));
declare(function);
return function;
}
protected MethodType onMethod(Method method, String name, Object[] parameters, Doc doc)
{
MethodType function = new MethodBase(this, method, name, parameters, doc);
putstatic(_class, "m_" + name, function);
putstatic(_class, "M_" + name, new AnyFunction(function));
declare(function);
return function;
}
protected MethodType onInterfaceMethod(Method method, String name, Object[] parameters, Doc doc)
{
MethodType function = new InterfaceMethodBase(this, method, name, parameters, doc);
putstatic(_class, "m_" + name, function);
putstatic(_class, "M_" + name, new AnyFunction(function));
declare(function);
return function;
}
protected MethodType onConstructor(Method method, Constructor constructor, String name, Object[] parameters, Doc doc)
{
MethodType function = new ConstructorBase(this, constructor, method, name, parameters, doc);
putfield(_class, null, "m_" + name, function);
putfield(_class, null, "M_" + name, new AnyFunction(function));
declare(function);
return function;
}
protected ConstantVariableType onConstantVariable(Field field, String name, Doc doc)
{
ConstantVariableType constant = new ConstantVariable(this, name, field, doc);
_types.put(name, constant);
return constant;
}
protected StaticVariableType onStaticVariable(Field field, String name, Doc doc)
{
StaticVariableType variable = new StaticVariable(this, name, field, doc);
_types.put(name, variable);
return variable;
}
protected MemberVariableType onMemberVariable(Field field, String name, Doc doc)
{
MemberVariableType variable = new MemberVariable(this, name, field, doc);
_types.put(name, variable);
return variable;
}
public Type lookupDeclaration(String name)
{
return (Type)_types.get(name);
}
public final Enumeration getDeclarations()
{
return _types.elements();
}
protected final void declare(Type type)
{
_types.put(type.getName(), type);
}
protected final void declare(String name, Type type)
{
_types.put(name, type);
}
public int getTypeRef(anvil.codec.ConstantPool pool)
{
return pool.addClass(_descriptor);
}
public String getDescriptor()
{
return _descriptor;
}
public CompiledModule getModule()
{
Type type = this;
while(type != null) {
Type parent = type.getParent();
if (parent == null) {
return (CompiledModule)type;
}
type = parent;
}
return null;
}
public String buildQualifiedName()
{
StringBuffer buffer = new StringBuffer(24);
Scope scope = this;
out: while(true) {
switch(scope.getType()) {
case CLASS:
case NAMESPACE:
if (buffer.length()>0) {
buffer.insert(0, '.');
}
buffer.insert(0, scope.getName());
scope = scope.getParent();
break;
default:
break out;
}
}
return buffer.toString();
}
}