/*
* Copyright (C) 2010 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package lombok.ast.grammar;
import java.util.Collections;
import java.util.List;
import com.google.common.collect.Lists;
import lombok.ast.AlternateConstructorInvocation;
import lombok.ast.Assert;
import lombok.ast.Block;
import lombok.ast.Break;
import lombok.ast.Case;
import lombok.ast.Catch;
import lombok.ast.Continue;
import lombok.ast.Default;
import lombok.ast.DoWhile;
import lombok.ast.EmptyStatement;
import lombok.ast.ExpressionStatement;
import lombok.ast.For;
import lombok.ast.ForEach;
import lombok.ast.If;
import lombok.ast.LabelledStatement;
import lombok.ast.Node;
import lombok.ast.Position;
import lombok.ast.Return;
import lombok.ast.SuperConstructorInvocation;
import lombok.ast.Switch;
import lombok.ast.Synchronized;
import lombok.ast.Throw;
import lombok.ast.Try;
import lombok.ast.VariableDeclaration;
import lombok.ast.VariableDefinition;
import lombok.ast.VariableDefinitionEntry;
import lombok.ast.While;
public class StatementsActions extends SourceActions {
public StatementsActions(Source source) {
super(source);
}
public Node createBlock(List<Node> statements) {
Block block = new Block();
if (statements != null) for (Node s : statements) {
if (s != null) block.rawContents().addToEnd(s);
}
return posify(block);
}
public Node createEmptyStatement() {
return posify(new EmptyStatement());
}
public Node createLabelledStatement(List<Node> labelNames, Node statement) {
Node current = statement;
if (labelNames != null) {
labelNames = Lists.newArrayList(labelNames);
Collections.reverse(labelNames);
for (Node n : labelNames) {
if (n != null) {
Position pos = current == null ? null : new Position(n.getPosition().getStart(), current.getPosition().getEnd());
current = new LabelledStatement().astLabel(createIdentifierIfNeeded(n, currentPos())).rawStatement(current);
current.setPosition(pos);
}
}
}
return current;
}
public Node createIfStatement(Node condition, Node statement, Node elseStatement) {
return posify(new If().rawCondition(condition).rawStatement(statement).rawElseStatement(elseStatement));
}
public Node createAssertStatement(Node assertion, Node message) {
return posify(new Assert().rawAssertion(assertion).rawMessage(message));
}
public Node createSwitchStatement(Node condition, Node body) {
return posify(new Switch().rawCondition(condition).rawBody(body));
}
public Node createCaseStatement(Node condition) {
return posify(new Case().rawCondition(condition));
}
public Node createDefaultStatement(org.parboiled.Node<Node> defaultStatement) {
Default node = new Default();
source.registerStructure(node, defaultStatement);
return posify(node);
}
public Node createWhileStatement(Node condition, Node statement) {
return posify(new While().rawCondition(condition).rawStatement(statement));
}
public Node createDoStatement(Node condition, Node statement) {
return posify(new DoWhile().rawCondition(condition).rawStatement(statement));
}
public Node createStatementExpressionList(Node head, List<Node> tail) {
TemporaryNode.StatementExpressionList result = new TemporaryNode.StatementExpressionList();
if (head != null) result.expressions.add(head);
if (tail != null) for (Node n : tail) if (n != null) result.expressions.add(n);
return posify(result);
}
public Node createBasicFor(Node init, Node condition, Node update, Node statement) {
For result = new For().rawCondition(condition).rawStatement(statement);
List<Node> updates;
if (update instanceof TemporaryNode.StatementExpressionList) {
updates = ((TemporaryNode.StatementExpressionList)update).expressions;
} else {
updates = Collections.singletonList(update);
}
if (init instanceof TemporaryNode.StatementExpressionList) {
for (Node n : ((TemporaryNode.StatementExpressionList)init).expressions) result.rawExpressionInits().addToEnd(n);
} else {
result.rawVariableDeclaration(init);
}
for (Node n : updates) if (n != null) result.rawUpdates().addToEnd(n);
return posify(result);
}
public Node createEnhancedFor(
org.parboiled.Node<Node> modifiers, Node type,
org.parboiled.Node<Node> varDefEntry, Node iterable, Node statement) {
VariableDefinition decl = new VariableDefinition().rawTypeReference(type).rawVariables()
.addToEnd(varDefEntry.getValue());
positionSpan(decl, modifiers, varDefEntry);
decl.astModifiers(createModifiersIfNeeded(modifiers.getValue(), decl.getPosition().getStart()));
return posify(new ForEach().rawVariable(decl).rawIterable(iterable).rawStatement(statement));
}
public Node createBreak(Node label) {
Break b = new Break();
if (label != null) b.astLabel(createIdentifierIfNeeded(label, currentPos()));
return posify(b);
}
public Node createContinue(Node label) {
Continue c = new Continue();
if (label != null) c.astLabel(createIdentifierIfNeeded(label, currentPos()));
return posify(c);
}
public Node createReturn(Node value) {
return posify(new Return().rawValue(value));
}
public Node createThrow(Node throwable) {
return posify(new Throw().rawThrowable(throwable));
}
public Node createSynchronizedStatement(Node lock, Node body) {
return posify(new Synchronized().rawLock(lock).rawBody(body));
}
public Node createCatch(Node modifiers, Node type, Node varName, Node body) {
VariableDefinitionEntry varNameEntry = new VariableDefinitionEntry().astName(createIdentifierIfNeeded(varName, currentPos()));
if (varName != null) varNameEntry.setPosition(varName.getPosition());
VariableDefinition decl = new VariableDefinition().rawTypeReference(type).rawVariables().addToEnd(
varNameEntry);
if (type != null && varName != null) decl.setPosition(new Position(type.getPosition().getStart(), varName.getPosition().getEnd()));
if (modifiers != null) decl.astModifiers(createModifiersIfNeeded(modifiers, currentPos()));
return posify(new Catch().rawExceptionDeclaration(decl).rawBody(body));
}
public Node createTryStatement(Node body, List<Node> catches, Node finallyBody) {
Try result = new Try().rawBody(body).rawFinally(finallyBody);
if (catches != null) for (Node c : catches) if (c != null) result.rawCatches().addToEnd(c);
return posify(result);
}
public Node addLocalVariableModifiers(Node variableDefinition, Node modifiers) {
if (modifiers != null && variableDefinition instanceof VariableDefinition) {
((VariableDefinition)variableDefinition).astModifiers(createModifiersIfNeeded(modifiers, currentPos()));
}
return posify(variableDefinition);
}
public Node createAlternateConstructorInvocation(Node typeArguments, Node arguments) {
AlternateConstructorInvocation result = new AlternateConstructorInvocation();
if (typeArguments instanceof TemporaryNode.TypeArguments) {
for (Node arg : ((TemporaryNode.TypeArguments)typeArguments).arguments) {
result.rawConstructorTypeArguments().addToEnd(arg);
}
}
if (arguments instanceof TemporaryNode.MethodArguments) {
for (Node arg : ((TemporaryNode.MethodArguments)arguments).arguments) {
result.rawArguments().addToEnd(arg);
}
}
return posify(result);
}
public Node createSuperConstructorInvocation(org.parboiled.Node<Node> dot, Node qualifier, Node typeArguments, Node arguments) {
SuperConstructorInvocation result = new SuperConstructorInvocation().rawQualifier(qualifier);
if (typeArguments instanceof TemporaryNode.TypeArguments) {
for (Node arg : ((TemporaryNode.TypeArguments)typeArguments).arguments) {
result.rawConstructorTypeArguments().addToEnd(arg);
}
}
if (arguments instanceof TemporaryNode.MethodArguments) {
for (Node arg : ((TemporaryNode.MethodArguments)arguments).arguments) {
result.rawArguments().addToEnd(arg);
}
}
if (dot != null) source.registerStructure(result, dot);
return posify(result);
}
public Node createExpressionStatement(Node expression) {
return posify(new ExpressionStatement().rawExpression(expression));
}
public Node createVariableDeclaration(Node definition) {
return posify(new VariableDeclaration().rawDefinition(definition));
}
}