001: /*
002: * $Id: AnyFunction.java,v 1.27 2002/09/16 08:05:03 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.core.runtime;
011:
012: import java.io.IOException;
013: import java.io.Writer;
014: import anvil.core.Any;
015: import anvil.core.AnyClass;
016: import anvil.core.AnyAbstractClass;
017: import anvil.core.Serializer;
018: import anvil.core.Unserializer;
019: import anvil.core.UnserializationException;
020: import anvil.doc.Doc;
021: import anvil.script.Context;
022: import anvil.script.CompilableFunction;
023: import anvil.script.ClassType;
024: import anvil.script.Type;
025: import anvil.script.Function;
026: import anvil.script.Grammar;
027: import anvil.script.Module;
028: import anvil.script.StackFrame;
029: import anvil.script.Scope;
030:
031: /// @class Function
032: /// Function is a callable wrapper for functions and methods.
033:
034: /**
035: * class AnyFunction
036: *
037: * @author: Jani Lehtimäki
038: */
039: public class AnyFunction extends AnyAbstractClass //implements Function
040: {
041:
042: public static final anvil.script.compiler.NativeClass __class__ = new anvil.script.compiler.NativeClass(
043: "Function",
044: AnyFunction.class,
045: //DOC{{
046: ""
047: + " @class Function\n"
048: + " Function is a callable wrapper for functions and methods.\n"
049: //}}DOC
050: );
051: static {
052: RuntimeModule.class.getName();
053: }
054:
055: private Any _self;
056: private Function _function;
057: private StackFrame _escape;
058:
059: private AnyFunction() {
060: }
061:
062: public AnyFunction(Function function) {
063: super ();
064: _function = function;
065: }
066:
067: public AnyFunction(Function function, StackFrame escape) {
068: super ();
069: _function = function;
070: _escape = escape;
071: }
072:
073: public AnyFunction(Any self, Function function) {
074: super ();
075: _self = self;
076: _function = function;
077: }
078:
079: public AnyFunction(Any self, Function function, StackFrame escape) {
080: super ();
081: _self = self;
082: _function = function;
083: _escape = escape;
084: }
085:
086: public final anvil.script.ClassType classOf() {
087: return __class__;
088: }
089:
090: public final Type type() {
091: return _function;
092: }
093:
094: public String toString() {
095: return _function.toString();
096: }
097:
098: public String getName() {
099: return _function.getName();
100: }
101:
102: public int getType() {
103: return _function.getType();
104: }
105:
106: public Scope getParent() {
107: return _function.getParent();
108: }
109:
110: public Doc getDocument() {
111: return _function.getDocument();
112: }
113:
114: public Any getSelf() {
115: return _self;
116: }
117:
118: public Function getFunction() {
119: return _function;
120: }
121:
122: public Writer toAnvil(Writer writer) throws IOException {
123: writer.write(_function.getName());
124: return writer;
125: }
126:
127: public Object toObject() {
128: return this ;
129: }
130:
131: public Function toFunction() {
132: return _function;
133: }
134:
135: public Any getAttribute(Context context, String attr) {
136: if (_function instanceof CompilableFunction) {
137: Any value = ((CompilableFunction) _function)
138: .getAttribute(attr);
139: if (value != null) {
140: return value;
141: }
142: }
143: return UNDEFINED;
144: }
145:
146: public Any checkAttribute(Context context, String attr) {
147: return getAttribute(context, attr);
148: }
149:
150: public Any getReference(Context context, Any index) {
151: return getAttribute(context, index.toString());
152: }
153:
154: public Any checkReference(Context context, Any index) {
155: return getAttribute(context, index.toString());
156: }
157:
158: public Any execute(Context context, Any[] parameters) {
159: if (_escape != null) {
160: context.setEscape(_escape);
161: }
162: return _function.execute(context, _self, parameters);
163: }
164:
165: public Any execute(Context context) {
166: if (_escape != null) {
167: context.setEscape(_escape);
168: }
169: return _function.execute(context, _self);
170: }
171:
172: public Any execute(Context context, Any param1) {
173: if (_escape != null) {
174: context.setEscape(_escape);
175: }
176: return _function.execute(context, _self, param1);
177: }
178:
179: public Any execute(Context context, Any param1, Any param2) {
180: if (_escape != null) {
181: context.setEscape(_escape);
182: }
183: return _function.execute(context, _self, param1, param2);
184: }
185:
186: public Any execute(Context context, Any param1, Any param2,
187: Any param3) {
188: if (_escape != null) {
189: context.setEscape(_escape);
190: }
191: return _function
192: .execute(context, _self, param1, param2, param3);
193: }
194:
195: public Any execute(Context context, Any param1, Any param2,
196: Any param3, Any param4) {
197: if (_escape != null) {
198: context.setEscape(_escape);
199: }
200: return _function.execute(context, _self, param1, param2,
201: param3, param4);
202: }
203:
204: public final void serialize(Serializer serializer)
205: throws IOException {
206: if (serializer.register(this )) {
207: return;
208: }
209: if (_escape != null) {
210: serializer.write('Z');
211: AnyType.serializeType(serializer, _function);
212: if (_self != null) {
213: _self.serialize(serializer);
214: } else {
215: serializer.write('n');
216: }
217: _escape.serialize(serializer);
218: return;
219: }
220:
221: if (_self != null) {
222: serializer.write('D');
223: _self.serialize(serializer);
224: serializer.write(_function.getName());
225:
226: } else if (_function instanceof CompilableFunction) {
227: serializer.write('c');
228: AnyType.serializeType(serializer, _function);
229:
230: } else {
231: super .serialize(serializer);
232: }
233: }
234:
235: public static final Any unserialize(Unserializer unserializer)
236: throws UnserializationException {
237: AnyFunction function = new AnyFunction();
238: unserializer.register(function);
239: Type type = AnyType.unserializeType(unserializer);
240: switch (type.getType()) {
241: case Type.FUNCTION:
242: case Type.METHOD:
243: function._function = (Function) type;
244: return function;
245: }
246: throw new UnserializationException();
247: }
248:
249: public static final Any unserializeClosure(Unserializer unserializer)
250: throws UnserializationException {
251: AnyFunction function = new AnyFunction();
252: unserializer.register(function);
253: Type type = AnyType.unserializeType(unserializer);
254: AnyClass self = null;
255: if (unserializer.peek() == 'n') {
256: unserializer.consume('n');
257: } else {
258: self = (AnyClass) unserializer.unserialize();
259: }
260: switch (type.getType()) {
261: case Type.FUNCTION:
262: case Type.METHOD: {
263: Function func = (Function) type;
264: function._self = self;
265: function._function = func;
266: function._escape = StackFrame.unserialize(unserializer,
267: Grammar.getModuleOf(func), self, func);
268: return function;
269: }
270: }
271: throw new UnserializationException();
272: }
273:
274: public static final Any unserializeDelegate(
275: Unserializer unserializer) throws UnserializationException {
276: AnyFunction delegate = new AnyFunction();
277: unserializer.register(delegate);
278: Any self = unserializer.unserialize();
279: unserializer.consume('s');
280: String name = unserializer.getUTF16String();
281: Type type = self.classOf().lookupDeclaration(name);
282: if (type != null) {
283: if (type.getType() == Type.METHOD) {
284: delegate._function = (Function) type;
285: delegate._self = self;
286: return delegate;
287: }
288: }
289: throw new UnserializationException(
290: "Delegate does not point to class-method pair");
291: }
292:
293: public int getTypeRef(anvil.codec.ConstantPool pool) {
294: return 0;
295: }
296:
297: }
|