/*
* $Id: AnyFunction.java,v 1.27 2002/09/16 08:05:03 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.core.runtime;
import java.io.IOException;
import java.io.Writer;
import anvil.core.Any;
import anvil.core.AnyClass;
import anvil.core.AnyAbstractClass;
import anvil.core.Serializer;
import anvil.core.Unserializer;
import anvil.core.UnserializationException;
import anvil.doc.Doc;
import anvil.script.Context;
import anvil.script.CompilableFunction;
import anvil.script.ClassType;
import anvil.script.Type;
import anvil.script.Function;
import anvil.script.Grammar;
import anvil.script.Module;
import anvil.script.StackFrame;
import anvil.script.Scope;
/// @class Function
/// Function is a callable wrapper for functions and methods.
/**
* class AnyFunction
*
* @author: Jani Lehtim�ki
*/
public class AnyFunction extends AnyAbstractClass //implements Function
{
public static final anvil.script.compiler.NativeClass __class__ =
new anvil.script.compiler.NativeClass("Function", AnyFunction.class,
//DOC{{
""+
" @class Function\n" +
" Function is a callable wrapper for functions and methods.\n"
//}}DOC
);
static {
RuntimeModule.class.getName();
}
private Any _self;
private Function _function;
private StackFrame _escape;
private AnyFunction()
{
}
public AnyFunction(Function function)
{
super();
_function = function;
}
public AnyFunction(Function function, StackFrame escape)
{
super();
_function = function;
_escape = escape;
}
public AnyFunction(Any self, Function function)
{
super();
_self = self;
_function = function;
}
public AnyFunction(Any self, Function function, StackFrame escape)
{
super();
_self = self;
_function = function;
_escape = escape;
}
public final anvil.script.ClassType classOf()
{
return __class__;
}
public final Type type()
{
return _function;
}
public String toString()
{
return _function.toString();
}
public String getName()
{
return _function.getName();
}
public int getType()
{
return _function.getType();
}
public Scope getParent()
{
return _function.getParent();
}
public Doc getDocument()
{
return _function.getDocument();
}
public Any getSelf()
{
return _self;
}
public Function getFunction()
{
return _function;
}
public Writer toAnvil(Writer writer) throws IOException
{
writer.write(_function.getName());
return writer;
}
public Object toObject()
{
return this;
}
public Function toFunction()
{
return _function;
}
public Any getAttribute(Context context, String attr)
{
if (_function instanceof CompilableFunction) {
Any value = ((CompilableFunction)_function).getAttribute(attr);
if (value != null) {
return value;
}
}
return UNDEFINED;
}
public Any checkAttribute(Context context, String attr)
{
return getAttribute(context, attr);
}
public Any getReference(Context context, Any index)
{
return getAttribute(context, index.toString());
}
public Any checkReference(Context context, Any index)
{
return getAttribute(context, index.toString());
}
public Any execute(Context context, Any[] parameters)
{
if (_escape != null) {
context.setEscape(_escape);
}
return _function.execute(context, _self, parameters);
}
public Any execute(Context context)
{
if (_escape != null) {
context.setEscape(_escape);
}
return _function.execute(context, _self);
}
public Any execute(Context context, Any param1)
{
if (_escape != null) {
context.setEscape(_escape);
}
return _function.execute(context, _self, param1);
}
public Any execute(Context context, Any param1, Any param2)
{
if (_escape != null) {
context.setEscape(_escape);
}
return _function.execute(context, _self, param1, param2);
}
public Any execute(Context context, Any param1, Any param2, Any param3)
{
if (_escape != null) {
context.setEscape(_escape);
}
return _function.execute(context, _self, param1, param2, param3);
}
public Any execute(Context context, Any param1, Any param2, Any param3, Any param4)
{
if (_escape != null) {
context.setEscape(_escape);
}
return _function.execute(context, _self, param1, param2, param3, param4);
}
public final void serialize(Serializer serializer) throws IOException
{
if (serializer.register(this)) {
return;
}
if (_escape != null) {
serializer.write('Z');
AnyType.serializeType(serializer, _function);
if (_self != null) {
_self.serialize(serializer);
} else {
serializer.write('n');
}
_escape.serialize(serializer);
return;
}
if (_self != null) {
serializer.write('D');
_self.serialize(serializer);
serializer.write(_function.getName());
} else if (_function instanceof CompilableFunction) {
serializer.write('c');
AnyType.serializeType(serializer, _function);
} else {
super.serialize(serializer);
}
}
public static final Any unserialize(Unserializer unserializer) throws UnserializationException
{
AnyFunction function = new AnyFunction();
unserializer.register(function);
Type type = AnyType.unserializeType(unserializer);
switch(type.getType()) {
case Type.FUNCTION:
case Type.METHOD:
function._function = (Function)type;
return function;
}
throw new UnserializationException();
}
public static final Any unserializeClosure(Unserializer unserializer) throws UnserializationException
{
AnyFunction function = new AnyFunction();
unserializer.register(function);
Type type = AnyType.unserializeType(unserializer);
AnyClass self = null;
if (unserializer.peek() == 'n') {
unserializer.consume('n');
} else {
self = (AnyClass)unserializer.unserialize();
}
switch(type.getType()) {
case Type.FUNCTION:
case Type.METHOD:
{
Function func = (Function)type;
function._self = self;
function._function = func;
function._escape = StackFrame.unserialize(unserializer, Grammar.getModuleOf(func), self, func);
return function;
}
}
throw new UnserializationException();
}
public static final Any unserializeDelegate(Unserializer unserializer) throws UnserializationException
{
AnyFunction delegate = new AnyFunction();
unserializer.register(delegate);
Any self = unserializer.unserialize();
unserializer.consume('s');
String name = unserializer.getUTF16String();
Type type = self.classOf().lookupDeclaration(name);
if (type != null) {
if (type.getType() == Type.METHOD) {
delegate._function = (Function)type;
delegate._self = self;
return delegate;
}
}
throw new UnserializationException("Delegate does not point to class-method pair");
}
public int getTypeRef(anvil.codec.ConstantPool pool)
{
return 0;
}
}