/*
* $Id: BlockStatement.java,v 1.5 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.core.Any;
import anvil.Location;
import anvil.codec.Code;
import anvil.codec.Source;
import anvil.codec.Target;
import anvil.parser.Tag;
import anvil.ErrorListener;
import anvil.script.compiler.ByteCompiler;
import anvil.script.Context;
import anvil.script.expression.Expression;
import anvil.script.parser.TemplateParser;
import java.io.IOException;
import java.util.ArrayList;
/**
* class BlockStatement
*
* @author: Jani Lehtim�ki
*/
public abstract class BlockStatement extends ScopedStatement
{
private ArrayList _statements = new ArrayList();
private Statement _head = null;
private Statement _tail = null;
private boolean _isblocked = false;
private Source _startscope;
private Source _endscope;
public BlockStatement(Statement parent, Location location)
{
super(parent, location);
}
public abstract int typeOf();
public String name()
{
return "block";
}
public BlockStatement getBlockStatement()
{
return this;
}
public Statement getChildStatement()
{
throw new RuntimeException("getChildStatement called on "+getClass());
}
public void setChildStatement(Statement statement)
{
add(statement);
}
public TryStatement replaceWithTry()
{
Location location = getLocation();
TryStatement trystmt = new TryStatement(this, location);
ImplicitBlockStatement block = new ImplicitBlockStatement(trystmt, location);
trystmt.setChildStatement(block);
int n = _statements.size();
for(int i=0; i<n; i++) {
Statement stmt = (Statement)_statements.get(i);
stmt.setParentStatement(block);
block.add(stmt);
}
_statements.clear();
_statements.add(trystmt);
return trystmt;
}
public void add(Statement statement)
{
_statements.add(statement);
}
public void insert(Statement statement)
{
_statements.add(0, statement);
}
public void insert(BlockStatement block)
{
_statements.addAll(0, block._statements);
}
public void insert(Statement after, BlockStatement block)
{
int i = _statements.indexOf(after);
if (i < 0) {
i = 0;
}
_statements.addAll(i, block._statements);
}
public boolean isEmpty()
{
return _statements.isEmpty();
}
public Statement getHead()
{
if (_statements.size()>0) {
return (Statement)_statements.get(0);
} else {
return null;
}
}
public Statement getTail()
{
int n = _statements.size();
if (n>0) {
return (Statement)_statements.get(n-1);
} else {
return null;
}
}
public void check(ErrorListener context)
{
int n = _statements.size();
for(int i=0; i<n; i++) {
((Statement)_statements.get(i)).check(context);
}
StringBuffer buffer = new StringBuffer();
int i = 0;
while(i < _statements.size()) {
Statement stmt = (Statement)_statements.get(i);
if (i+1 < _statements.size() && stmt.hasStaticContent()) {
Statement next = (Statement)_statements.get(i+1);
if (next.hasStaticContent()) {
Location location = stmt.getLocation();
buffer.setLength(0);
buffer.append(stmt.getStaticContent());
buffer.append(next.getStaticContent());
_statements.remove(i);
_statements.remove(i);
while (i < _statements.size()) {
stmt = (Statement)_statements.get(i);
if (!stmt.hasStaticContent()) {
break;
}
_statements.remove(i);
buffer.append(stmt.getStaticContent());
}
_statements.add(i, new CharacterDataStatement(this, location, buffer.toString()));
}
}
i++;
}
}
public boolean isBlocked()
{
return _isblocked;
}
public Jumps eliminate(ErrorListener context)
{
Jumps jumps = new Jumps();
int n = _statements.size();
for(int i=0; i<n; i++) {
Statement stmt = (Statement)_statements.get(i);
if (jumps.isBlocked()) {
if (context != null) {
int type = stmt.typeOf();
if (type != Statement.ST_TAG && type != Statement.ST_CDATA) {
context.error(stmt.getLocation(),
"Dead code: " + stmt.name() + " statement not reached");
}
}
} else {
Jumps j = stmt.eliminate(context);
//if (j.isBlocked() && !jumps.isBlocked()) {
//}
jumps.merge(j);
}
}
_isblocked = jumps.isBlocked();
return jumps;
}
public Source getStartOfScope()
{
return _startscope;
}
public Source getEndOfScope()
{
return _endscope;
}
public void compile(ByteCompiler context)
{
Code code = context.getCode();
Target start = code.getTarget();
_startscope = code.getSource();
_endscope = code.getSource();
int n = _statements.size();
for(int i=0; i<n; i++) {
Statement stmt = (Statement)_statements.get(i);
stmt.compile(context);
}
_endscope.bind();
_startscope.bind(start);
}
}