001: /*
002: * $Id: InvokeStatement.java,v 1.12 2002/09/16 08:05:06 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.script.statements;
011:
012: import anvil.Location;
013: import anvil.parser.Tag;
014: import anvil.ErrorListener;
015: import anvil.script.compiler.ByteCompiler;
016: import anvil.script.Context;
017: import anvil.script.expression.Expression;
018: import anvil.script.expression.ExpressionList;
019: import anvil.script.expression.InvokeNode;
020: import anvil.script.expression.LinkNode;
021: import anvil.script.expression.Node;
022: import anvil.script.expression.Parent;
023: import anvil.script.Name;
024: import anvil.script.Type;
025: import anvil.script.parser.ExpressionParser;
026: import anvil.script.parser.TemplateParser;
027: import anvil.script.parser.ParserBase;
028: import anvil.script.Grammar;
029: import java.io.IOException;
030:
031: /**
032: * class InvokeStatement
033: *
034: * @author: Jani Lehtimäki
035: */
036: public class InvokeStatement extends EvalStatement {
037:
038: public InvokeStatement(Statement parent, Location location) {
039: super (parent, location);
040: }
041:
042: public int typeOf() {
043: return Statement.ST_INVOKE;
044: }
045:
046: public String name() {
047: return "invoke";
048: }
049:
050: public void parse(TemplateParser parser, Tag tag) {
051: Location location = getLocation();
052: Parent parameters;
053:
054: String params = tag.getValue("params");
055: if (params != null) {
056: ExpressionParser p = new ExpressionParser(parser, location,
057: params);
058: parameters = p.parseParameterList();
059:
060: } else {
061: int size = 0;
062: int n = tag.getLength();
063: for (int i = 0; i < n; i++) {
064: if (tag.getName(i).equalsIgnoreCase("param")) {
065: size++;
066: }
067: }
068: parameters = new ExpressionList(size);
069: int c = 0;
070: for (int i = 0; i < n; i++) {
071: if (tag.getName(i).equalsIgnoreCase("param")) {
072: Expression expression = Grammar.parseExpression(tag
073: .getValue(i), location, parser);
074: parameters.setChild(c++, expression);
075: }
076: }
077: }
078:
079: String from = tag.getValue("from");
080: String method = tag.getValue("method");
081: boolean is_super = tag.contains("super");
082:
083: if ((method != null) && !Grammar.isValidIdentifier(method)) {
084: parser
085: .error(location, "Method '" + method
086: + "' is invalid");
087: return;
088: }
089:
090: if (is_super ) {
091: if (method == null) {
092: // super(params, ...)
093: Statement parent = getParentStatement();
094: FunctionStatement function = getFunctionStatement();
095: if (function.getType() == Type.CONSTRUCTOR) {
096: BlockStatement block = function.getBlockStatement();
097: if (parent == function && block.isEmpty()) {
098: _expression = new Expression(new LinkNode(this ,
099: location, new Name().add(Name.SUPER,
100: "super"), parameters,
101: LinkNode.SUPER), location);
102:
103: } else {
104: parser
105: .error(
106: location,
107: "Superclass constructor invoke must appear as a first statement (characters between tags are considered statements)");
108: }
109: } else {
110: parser
111: .error(location,
112: "Superclass constructor invoke may only appear in constructor");
113: }
114:
115: } else {
116: // super.method(params, ...)
117: _expression = new Expression(
118: new LinkNode(this , location, new Name().add(
119: Name.SUPER, "super").add(method),
120: parameters, LinkNode.GET), location);
121:
122: }
123:
124: } else {
125: if (method == null) {
126: parser.error(location, "Attribute 'method' not given");
127: return;
128: }
129:
130: if (from == null) {
131: // method(params, ...)
132: _expression = new Expression(new LinkNode(this ,
133: location, new Name().add(method), parameters,
134: LinkNode.GET), location);
135:
136: } else {
137: // expr.method(params, ...)
138: Expression self = Grammar.parseExpression(from,
139: location, parser);
140: _expression = new Expression(new InvokeNode(self,
141: method, parameters), location);
142:
143: }
144: }
145: }
146:
147: }
|