/*
* $Id: InvokeStatement.java,v 1.12 2002/09/16 08:05:06 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.statements;
import anvil.Location;
import anvil.parser.Tag;
import anvil.ErrorListener;
import anvil.script.compiler.ByteCompiler;
import anvil.script.Context;
import anvil.script.expression.Expression;
import anvil.script.expression.ExpressionList;
import anvil.script.expression.InvokeNode;
import anvil.script.expression.LinkNode;
import anvil.script.expression.Node;
import anvil.script.expression.Parent;
import anvil.script.Name;
import anvil.script.Type;
import anvil.script.parser.ExpressionParser;
import anvil.script.parser.TemplateParser;
import anvil.script.parser.ParserBase;
import anvil.script.Grammar;
import java.io.IOException;
/**
* class InvokeStatement
*
* @author: Jani Lehtim�ki
*/
public class InvokeStatement extends EvalStatement
{
public InvokeStatement(Statement parent, Location location)
{
super(parent, location);
}
public int typeOf()
{
return Statement.ST_INVOKE;
}
public String name()
{
return "invoke";
}
public void parse(TemplateParser parser, Tag tag)
{
Location location = getLocation();
Parent parameters;
String params = tag.getValue("params");
if (params != null) {
ExpressionParser p = new ExpressionParser(parser, location, params);
parameters = p.parseParameterList();
} else {
int size = 0;
int n = tag.getLength();
for (int i=0; i<n; i++) {
if (tag.getName(i).equalsIgnoreCase("param")) {
size++;
}
}
parameters = new ExpressionList(size);
int c = 0;
for (int i=0; i<n; i++) {
if (tag.getName(i).equalsIgnoreCase("param")) {
Expression expression = Grammar.parseExpression(tag.getValue(i), location, parser);
parameters.setChild(c++, expression);
}
}
}
String from = tag.getValue("from");
String method = tag.getValue("method");
boolean is_super = tag.contains("super");
if ((method != null) && !Grammar.isValidIdentifier(method)) {
parser.error(location, "Method '"+method+"' is invalid");
return;
}
if (is_super) {
if (method == null) {
// super(params, ...)
Statement parent = getParentStatement();
FunctionStatement function = getFunctionStatement();
if (function.getType() == Type.CONSTRUCTOR) {
BlockStatement block = function.getBlockStatement();
if (parent == function && block.isEmpty()) {
_expression = new Expression(new LinkNode(this, location,
new Name().add(Name.SUPER, "super"), parameters, LinkNode.SUPER), location);
} else {
parser.error(location, "Superclass constructor invoke must appear as a first statement (characters between tags are considered statements)");
}
} else {
parser.error(location, "Superclass constructor invoke may only appear in constructor");
}
} else {
// super.method(params, ...)
_expression = new Expression(new LinkNode(this, location,
new Name().add(Name.SUPER, "super").add(method), parameters, LinkNode.GET), location);
}
} else {
if (method == null) {
parser.error(location, "Attribute 'method' not given");
return;
}
if (from == null) {
// method(params, ...)
_expression = new Expression(new LinkNode(this, location,
new Name().add(method), parameters, LinkNode.GET), location);
} else {
// expr.method(params, ...)
Expression self = Grammar.parseExpression(from, location, parser);
_expression = new Expression(new InvokeNode(self, method, parameters), location);
}
}
}
}