/*
* ASTStatementList.java
*
* Copyright (c) 2006-2008 David Holroyd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package uk.co.badgersinfoil.metaas.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.asdt.core.internal.antlr.AS3Parser;
import uk.co.badgersinfoil.metaas.dom.ASBlock;
import uk.co.badgersinfoil.metaas.dom.ASBreakStatement;
import uk.co.badgersinfoil.metaas.dom.ASContinueStatement;
import uk.co.badgersinfoil.metaas.dom.ASDeclarationStatement;
import uk.co.badgersinfoil.metaas.dom.ASDefaultXMLNamespaceStatement;
import uk.co.badgersinfoil.metaas.dom.ASDoWhileStatement;
import uk.co.badgersinfoil.metaas.dom.Expression;
import uk.co.badgersinfoil.metaas.dom.ASExpressionStatement;
import uk.co.badgersinfoil.metaas.dom.ASForEachInStatement;
import uk.co.badgersinfoil.metaas.dom.ASForInStatement;
import uk.co.badgersinfoil.metaas.dom.ASForStatement;
import uk.co.badgersinfoil.metaas.dom.ASIfStatement;
import uk.co.badgersinfoil.metaas.dom.ASReturnStatement;
import uk.co.badgersinfoil.metaas.dom.ASSuperStatement;
import uk.co.badgersinfoil.metaas.dom.ASSwitchStatement;
import uk.co.badgersinfoil.metaas.dom.ASThrowStatement;
import uk.co.badgersinfoil.metaas.dom.ASTryStatement;
import uk.co.badgersinfoil.metaas.dom.ASWhileStatement;
import uk.co.badgersinfoil.metaas.dom.ASWithStatement;
import uk.co.badgersinfoil.metaas.dom.Statement;
import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListToken;
import uk.co.badgersinfoil.metaas.impl.antlr.LinkedListTree;
// TODO: make the ASBlock implementation independent of the StatementContainer implementation
/**
* Implements the behaviour of StatementContainer. May be managing statements
* for either be a block, or a switch-statement label.
*/
public class ASTStatementList extends ASTScriptElement implements ASBlock {
public ASTStatementList(LinkedListTree ast) {
super(ast);
assertBlockAST(ast);
}
private void assertBlockAST(LinkedListTree ast) {
switch (ast.getType()) {
case AS3Parser.BLOCK:
case AS3Parser.SWITCH_STATEMENT_LIST:
break;
default:
throw new IllegalArgumentException("statement is not a block: "+ASTUtils.tokenName(ast));
}
}
public Statement addStmt(String statement) {
LinkedListTree stmt = AS3FragmentParser.parseStatement(statement);
stmt.getStopToken().setNext(null);
addStatement(stmt);
return StatementBuilder.build(stmt);
}
public ASExpressionStatement newExprStmt(String expr) {
LinkedListTree stmt = AS3FragmentParser.parseExprStatement(expr);
addStatement(stmt);
return new ASTASExpressionStatement(stmt);
}
public ASExpressionStatement newExprStmt(Expression expr) {
LinkedListTree stmt = ASTBuilder.newExprStmt(ast(expr));
addStatement(stmt);
return new ASTASExpressionStatement(stmt);
}
public void addComment(String text) {
LinkedListToken comment = TokenBuilder.newSLComment("//" + text);
String indent = findIndentForComment();
ast.appendToken(TokenBuilder.newNewline());
ast.appendToken(TokenBuilder.newWhiteSpace(indent));
ast.appendToken(comment);
}
private String findIndentForComment() {
LinkedListTree last = ast.getLastChild();
String indent;
if (last == null) {
indent = "\t" + ASTUtils.findIndent(ast);
} else {
indent = ASTUtils.findIndent(last);
}
return indent;
}
public ASIfStatement newIf(String condition) {
LinkedListTree ifStmt = ASTBuilder.newIf(condition);
addStatement(ifStmt);
return new ASTASIfStatement(ifStmt);
}
public ASIfStatement newIf(Expression condition) {
LinkedListTree ifStmt = ASTBuilder.newIf(ast(condition));
addStatement(ifStmt);
return new ASTASIfStatement(ifStmt);
}
public ASForStatement newFor(String init, String condition, String iterate) {
LinkedListTree forStmt = ASTBuilder.newFor(init, condition, iterate);
appendBlock(forStmt);
addStatement(forStmt);
return new ASTASForStatement(forStmt);
}
public ASForStatement newFor(Expression init, Expression condition, Expression iterate) {
LinkedListTree forStmt = ASTBuilder.newFor(ast(init),
ast(condition),
ast(iterate));
appendBlock(forStmt);
addStatement(forStmt);
return new ASTASForStatement(forStmt);
}
public ASForInStatement newForIn(String declaration, String expression) {
LinkedListTree forStmt = ASTBuilder.newForIn(declaration, expression);
appendBlock(forStmt);
addStatement(forStmt);
return new ASTASForInStatement(forStmt);
}
public ASForInStatement newForIn(Expression declaration, Expression expression) {
LinkedListTree forStmt = ASTBuilder.newForIn(ast(declaration),
ast(expression));
appendBlock(forStmt);
addStatement(forStmt);
return new ASTASForInStatement(forStmt);
}
public ASForEachInStatement newForEachIn(String declaration, String expression) {
LinkedListTree forStmt = ASTBuilder.newForEachIn(declaration, expression);
appendBlock(forStmt);
addStatement(forStmt);
return new ASTASForEachInStatement(forStmt);
}
public ASForEachInStatement newForEachIn(Expression declaration, Expression expression) {
LinkedListTree forStmt = ASTBuilder.newForEachIn(ast(declaration),
ast(expression));
appendBlock(forStmt);
addStatement(forStmt);
return new ASTASForEachInStatement(forStmt);
}
public ASWhileStatement newWhile(String condition) {
LinkedListTree whileStmt = ASTBuilder.newWhile(condition);
appendBlock(whileStmt);
addStatement(whileStmt);
return new ASTASWhileStatement(whileStmt);
}
public ASWhileStatement newWhile(Expression condition) {
LinkedListTree whileStmt = ASTBuilder.newWhile(ast(condition));
appendBlock(whileStmt);
addStatement(whileStmt);
return new ASTASWhileStatement(whileStmt);
}
public ASDoWhileStatement newDoWhile(String condition) {
LinkedListTree doWhileStmt = ASTBuilder.newDoWhile(condition);
addStatement(doWhileStmt);
return new ASTASDoWhileStatement(doWhileStmt);
}
public ASDoWhileStatement newDoWhile(Expression condition) {
LinkedListTree doWhileStmt = ASTBuilder.newDoWhile(ast(condition));
addStatement(doWhileStmt);
return new ASTASDoWhileStatement(doWhileStmt);
}
public ASSwitchStatement newSwitch(String condition) {
LinkedListTree switchStmt = ASTBuilder.newSwitch(condition);
addStatement(switchStmt);
return new ASTASSwitchStatement(switchStmt);
}
public ASSwitchStatement newSwitch(Expression condition) {
LinkedListTree switchStmt = ASTBuilder.newSwitch(ast(condition));
addStatement(switchStmt);
return new ASTASSwitchStatement(switchStmt);
}
public ASWithStatement newWith(String expr) {
LinkedListTree withStmt = ASTBuilder.newWith(expr);
appendBlock(withStmt);
addStatement(withStmt);
return new ASTASWithStatement(withStmt);
}
public ASWithStatement newWith(Expression expr) {
LinkedListTree withStmt = ASTBuilder.newWith(ast(expr));
appendBlock(withStmt);
addStatement(withStmt);
return new ASTASWithStatement(withStmt);
}
public ASDeclarationStatement newDeclaration(String assignment) {
LinkedListTree declStmt = ASTBuilder.newDeclaration(assignment);
addStatement(declStmt);
return new ASTASDeclarationStatement(declStmt);
}
public ASDeclarationStatement newDeclaration(Expression assignment) {
LinkedListTree declStmt = ASTBuilder.newDeclaration(ast(assignment));
addStatement(declStmt);
return new ASTASDeclarationStatement(declStmt);
}
public ASReturnStatement newReturn(String expr) {
LinkedListTree returnStmt = ASTBuilder.newReturn(expr);
addStatement(returnStmt);
return new ASTASReturnStatement(returnStmt);
}
public ASReturnStatement newReturn(Expression expr) {
LinkedListTree returnStmt = ASTBuilder.newReturn(ast(expr));
addStatement(returnStmt);
return new ASTASReturnStatement(returnStmt);
}
public ASReturnStatement newReturn() {
LinkedListTree returnStmt = ASTBuilder.newReturn((String)null);
addStatement(returnStmt);
return new ASTASReturnStatement(returnStmt);
}
public ASSuperStatement newSuper(List args) {
LinkedListTree superStmt = ASTBuilder.newSuperStatement(args);
addStatement(superStmt);
return new ASTASSuperStatement(superStmt);
}
public ASBreakStatement newBreak() {
LinkedListTree breakStmt = ASTBuilder.newBreakStatement();
addStatement(breakStmt);
return new ASTASBreakStatement(breakStmt);
}
public ASTryStatement newTryCatch(String var, String type) {
LinkedListTree tryStmt = ASTBuilder.newTryStatement();
tryStmt.appendToken(TokenBuilder.newSpace());
tryStmt.addChildWithTokens(ASTBuilder.newCatchClause(var, type));
addStatement(tryStmt);
return new ASTASTryStatement(tryStmt);
}
public ASTryStatement newTryFinally() {
LinkedListTree tryStmt = ASTBuilder.newTryStatement();
tryStmt.appendToken(TokenBuilder.newSpace());
tryStmt.addChildWithTokens(ASTBuilder.newFinallyClause());
addStatement(tryStmt);
return new ASTASTryStatement(tryStmt);
}
public ASContinueStatement newContinue() {
LinkedListTree breakStmt = ASTBuilder.newContinueStatement();
addStatement(breakStmt);
return new ASTASContinueStatement(breakStmt);
}
public ASThrowStatement newThrow(Expression t) {
LinkedListTree throwStmt = ASTBuilder.newThrowStatement(ast(t));
addStatement(throwStmt);
return new ASTASThrowStatement(throwStmt);
}
public ASDefaultXMLNamespaceStatement newDefaultXMLNamespace(String namespace) {
LinkedListTree nsStmt = ASTBuilder.newDefaultXMLNamespace(ASTBuilder.newString(namespace));
addStatement(nsStmt);
return new ASTASDefaultXMLNamespaceStatement(nsStmt);
}
private void addStatement(LinkedListTree stmt) {
ASTUtils.addChildWithIndentation(ast, stmt);
}
public boolean containsCode() {
return ast.getFirstChild() != null;
}
public LinkedListTree getAST() {
return ast;
}
/**
* Appends a block node as a child of the given node (preceeding it
* with a space token) and returns a reference to the new block.
*
* NB doesn't do indentation properly, so add the block to the statement
* before the statement is added to its container.
*/
private static LinkedListTree appendBlock(LinkedListTree ast) {
ast.appendToken(TokenBuilder.newSpace());
LinkedListTree block = ASTBuilder.newBlock();
ast.addChildWithTokens(block);
return block;
}
/**
* Returns the first BLOCK child of the given node
*/
private static LinkedListTree findBlock(LinkedListTree ast) {
return (LinkedListTree)ast.getFirstChildWithType(AS3Parser.BLOCK);
}
public List getStatementList() {
List result = new ArrayList();
ASTIterator i = new ASTIterator(ast);
while (i.hasNext()) {
result.add(StatementBuilder.build(i.next()));
}
return Collections.unmodifiableList(result);
}
}