package org.dynjs.runtime.wrapper;
import java.util.List;
import org.dynjs.parser.Statement;
import org.dynjs.parser.ast.FunctionDeclaration;
import org.dynjs.parser.ast.VariableDeclaration;
import org.dynjs.runtime.*;
import org.dynjs.runtime.interp.InterpretedBasicBlock;
public class JavascriptFunction extends AbstractFunction {
private BasicBlock code;
public JavascriptFunction(final GlobalContext globalContext, final String identifier, final BasicBlock code, final LexicalEnvironment scope, final boolean strict, final String... formalParameters) {
super(globalContext, scope, strict, formalParameters);
this.code = code;
final DynObject proto = new DynObject(globalContext);
proto.defineOwnProperty(null, "constructor",
PropertyDescriptor.newDataPropertyDescriptor(JavascriptFunction.this, true, true, false), false);
defineOwnProperty(null, "prototype",
PropertyDescriptor.newDataPropertyDescriptor(proto, true, false, false), false);
defineOwnProperty(null, "name",
PropertyDescriptor.newDataPropertyDescriptor(identifier, true, true, false), false);
}
@Override
public String getFileName() {
return this.code.getFileName();
}
@Override
public Object call(ExecutionContext context) {
Completion result = this.code.call(context);
if (result.type == Completion.Type.RETURN) {
if (result.value == null) {
return Types.UNDEFINED;
}
return result.value;
}
return Types.UNDEFINED;
}
@Override
public List<FunctionDeclaration> getFunctionDeclarations() {
return this.code.getFunctionDeclarations();
}
@Override
public List<VariableDeclaration> getVariableDeclarations() {
return this.code.getVariableDeclarations();
}
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append("function(");
String[] params = getFormalParameters();
for (int i = 0; i < params.length; ++i) {
if (i > 0) {
buffer.append(", ");
}
buffer.append(params[i]);
}
buffer.append("){\n");
Statement statement = null;
if (code instanceof BasicBlockDelegate && ((BasicBlockDelegate) code).getDelegate() instanceof InterpretedBasicBlock) {
statement = ((InterpretedBasicBlock) ((BasicBlockDelegate) code).getDelegate()).getBody();
} else if (code instanceof InterpretedBasicBlock) {
statement = ((InterpretedBasicBlock) code).getBody();
}
if (statement != null) {
buffer.append(statement.toIndentedString(" "));
}
buffer.append("}");
return buffer.toString();
}
}