/*******************************************************************************
* Copyright (c) 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Zend Technologies
*******************************************************************************/
package org2.eclipse.php.internal.core.ast.rewrite;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org2.eclipse.php.core.compiler.PHPFlags;
import org2.eclipse.php.internal.core.PHPVersion;
import org2.eclipse.php.internal.core.ast.nodes.ASTError;
import org2.eclipse.php.internal.core.ast.nodes.ASTNode;
import org2.eclipse.php.internal.core.ast.nodes.ArrayAccess;
import org2.eclipse.php.internal.core.ast.nodes.ArrayCreation;
import org2.eclipse.php.internal.core.ast.nodes.ArrayElement;
import org2.eclipse.php.internal.core.ast.nodes.Assignment;
import org2.eclipse.php.internal.core.ast.nodes.BackTickExpression;
import org2.eclipse.php.internal.core.ast.nodes.Block;
import org2.eclipse.php.internal.core.ast.nodes.BreakStatement;
import org2.eclipse.php.internal.core.ast.nodes.CastExpression;
import org2.eclipse.php.internal.core.ast.nodes.CatchClause;
import org2.eclipse.php.internal.core.ast.nodes.ClassDeclaration;
import org2.eclipse.php.internal.core.ast.nodes.ClassInstanceCreation;
import org2.eclipse.php.internal.core.ast.nodes.ClassName;
import org2.eclipse.php.internal.core.ast.nodes.CloneExpression;
import org2.eclipse.php.internal.core.ast.nodes.Comment;
import org2.eclipse.php.internal.core.ast.nodes.ConditionalExpression;
import org2.eclipse.php.internal.core.ast.nodes.ConstantDeclaration;
import org2.eclipse.php.internal.core.ast.nodes.ContinueStatement;
import org2.eclipse.php.internal.core.ast.nodes.DeclareStatement;
import org2.eclipse.php.internal.core.ast.nodes.DoStatement;
import org2.eclipse.php.internal.core.ast.nodes.EchoStatement;
import org2.eclipse.php.internal.core.ast.nodes.EmptyStatement;
import org2.eclipse.php.internal.core.ast.nodes.Expression;
import org2.eclipse.php.internal.core.ast.nodes.ExpressionStatement;
import org2.eclipse.php.internal.core.ast.nodes.FieldAccess;
import org2.eclipse.php.internal.core.ast.nodes.FieldsDeclaration;
import org2.eclipse.php.internal.core.ast.nodes.ForEachStatement;
import org2.eclipse.php.internal.core.ast.nodes.ForStatement;
import org2.eclipse.php.internal.core.ast.nodes.FormalParameter;
import org2.eclipse.php.internal.core.ast.nodes.FunctionDeclaration;
import org2.eclipse.php.internal.core.ast.nodes.FunctionInvocation;
import org2.eclipse.php.internal.core.ast.nodes.FunctionName;
import org2.eclipse.php.internal.core.ast.nodes.GlobalStatement;
import org2.eclipse.php.internal.core.ast.nodes.GotoLabel;
import org2.eclipse.php.internal.core.ast.nodes.GotoStatement;
import org2.eclipse.php.internal.core.ast.nodes.Identifier;
import org2.eclipse.php.internal.core.ast.nodes.IfStatement;
import org2.eclipse.php.internal.core.ast.nodes.IgnoreError;
import org2.eclipse.php.internal.core.ast.nodes.InLineHtml;
import org2.eclipse.php.internal.core.ast.nodes.Include;
import org2.eclipse.php.internal.core.ast.nodes.InfixExpression;
import org2.eclipse.php.internal.core.ast.nodes.InstanceOfExpression;
import org2.eclipse.php.internal.core.ast.nodes.InterfaceDeclaration;
import org2.eclipse.php.internal.core.ast.nodes.LambdaFunctionDeclaration;
import org2.eclipse.php.internal.core.ast.nodes.ListVariable;
import org2.eclipse.php.internal.core.ast.nodes.MethodDeclaration;
import org2.eclipse.php.internal.core.ast.nodes.MethodInvocation;
import org2.eclipse.php.internal.core.ast.nodes.NamespaceDeclaration;
import org2.eclipse.php.internal.core.ast.nodes.NamespaceName;
import org2.eclipse.php.internal.core.ast.nodes.ParenthesisExpression;
import org2.eclipse.php.internal.core.ast.nodes.PostfixExpression;
import org2.eclipse.php.internal.core.ast.nodes.PrefixExpression;
import org2.eclipse.php.internal.core.ast.nodes.Program;
import org2.eclipse.php.internal.core.ast.nodes.Quote;
import org2.eclipse.php.internal.core.ast.nodes.Reference;
import org2.eclipse.php.internal.core.ast.nodes.ReflectionVariable;
import org2.eclipse.php.internal.core.ast.nodes.ReturnStatement;
import org2.eclipse.php.internal.core.ast.nodes.Scalar;
import org2.eclipse.php.internal.core.ast.nodes.SingleFieldDeclaration;
import org2.eclipse.php.internal.core.ast.nodes.Statement;
import org2.eclipse.php.internal.core.ast.nodes.StaticConstantAccess;
import org2.eclipse.php.internal.core.ast.nodes.StaticFieldAccess;
import org2.eclipse.php.internal.core.ast.nodes.StaticMethodInvocation;
import org2.eclipse.php.internal.core.ast.nodes.StaticStatement;
import org2.eclipse.php.internal.core.ast.nodes.StructuralPropertyDescriptor;
import org2.eclipse.php.internal.core.ast.nodes.SwitchCase;
import org2.eclipse.php.internal.core.ast.nodes.SwitchStatement;
import org2.eclipse.php.internal.core.ast.nodes.ThrowStatement;
import org2.eclipse.php.internal.core.ast.nodes.TryStatement;
import org2.eclipse.php.internal.core.ast.nodes.UnaryOperation;
import org2.eclipse.php.internal.core.ast.nodes.UseStatement;
import org2.eclipse.php.internal.core.ast.nodes.UseStatementPart;
import org2.eclipse.php.internal.core.ast.nodes.Variable;
import org2.eclipse.php.internal.core.ast.nodes.VariableBase;
import org2.eclipse.php.internal.core.ast.nodes.WhileStatement;
import org2.eclipse.php.internal.core.ast.visitor.AbstractVisitor;
@SuppressWarnings({"nls", "deprecation", "rawtypes"})
public class ASTRewriteFlattener extends AbstractVisitor {
public static String asString(ASTNode node, RewriteEventStore store) {
ASTRewriteFlattener flattener = new ASTRewriteFlattener(store);
node.accept(flattener);
return flattener.getResult();
}
protected StringBuffer result;
private RewriteEventStore store;
public ASTRewriteFlattener(RewriteEventStore store) {
this.store = store;
this.result = new StringBuffer();
}
/**
* Returns the string accumulated in the visit.
*
* @return the serialized
*/
public String getResult() {
// convert to a string, but lose any extra space in the string buffer by
// copying
return new String(this.result.toString());
}
/**
* Resets this printer so that it can be used again.
*/
public void reset() {
this.result.setLength(0);
}
/**
* Appends the text representation of the given modifier flags, followed by
* a single space.
*
* @param modifiers
* the modifiers
* @param buf
* The <code>StringBuffer</code> to write the result to.
*/
public static void printModifiers(int modifiers, StringBuffer buf) {
if (PHPFlags.isPublic(modifiers)) {
buf.append("public "); //$NON-NLS-1$
}
if (PHPFlags.isProtected(modifiers)) {
buf.append("protected "); //$NON-NLS-1$
}
if (PHPFlags.isPrivate(modifiers)) {
buf.append("private "); //$NON-NLS-1$
}
if (PHPFlags.isStatic(modifiers)) {
buf.append("static "); //$NON-NLS-1$
}
if (PHPFlags.isAbstract(modifiers)) {
buf.append("abstract "); //$NON-NLS-1$
}
if (PHPFlags.isFinal(modifiers)) {
buf.append("final "); //$NON-NLS-1$
}
}
protected List getChildList(ASTNode parent,
StructuralPropertyDescriptor childProperty) {
Object ret = getAttribute(parent, childProperty);
if (ret instanceof List) {
return (List) ret;
}
return Collections.EMPTY_LIST;
}
protected ASTNode getChildNode(ASTNode parent,
StructuralPropertyDescriptor childProperty) {
return (ASTNode) getAttribute(parent, childProperty);
}
protected int getIntAttribute(ASTNode parent,
StructuralPropertyDescriptor childProperty) {
return ((Integer) getAttribute(parent, childProperty)).intValue();
}
protected boolean getBooleanAttribute(ASTNode parent,
StructuralPropertyDescriptor childProperty) {
return ((Boolean) getAttribute(parent, childProperty)).booleanValue();
}
protected Object getAttribute(ASTNode parent,
StructuralPropertyDescriptor childProperty) {
if (store != null)
return this.store.getNewValue(parent, childProperty);
return null;
}
protected void visitList(ASTNode parent,
StructuralPropertyDescriptor childProperty, String separator) {
List list = getChildList(parent, childProperty);
for (int i = 0; i < list.size(); i++) {
if (separator != null && i > 0) {
this.result.append(separator);
}
((ASTNode) list.get(i)).accept(this);
}
}
protected void visitList(ASTNode parent,
StructuralPropertyDescriptor childProperty, String separator,
String lead, String post) {
List list = getChildList(parent, childProperty);
if (!list.isEmpty()) {
this.result.append(lead);
for (int i = 0; i < list.size(); i++) {
if (separator != null && i > 0) {
this.result.append(separator);
}
((ASTNode) list.get(i)).accept(this);
}
this.result.append(post);
}
}
/*
* (non-Javadoc)
*
* @see
* org2.eclipse.php.internal.core.ast.visitor.AbstractVisitor#visit(org.eclipse
* .php.internal.core.ast.nodes.ArrayAccess)
*/
public boolean visit(ArrayAccess arrayAccess) {
if (arrayAccess.getName() != null) {
arrayAccess.getName().accept(this);
}
boolean isVariableHashtable = arrayAccess.getArrayType() == ArrayAccess.VARIABLE_HASHTABLE;
if (isVariableHashtable) {
result.append('{');
} else {
result.append('[');
}
if (arrayAccess.getIndex() != null) {
arrayAccess.getIndex().accept(this);
}
if (isVariableHashtable) {
result.append('}');
} else {
result.append(']');
}
return false;
}
public boolean visit(ArrayCreation arrayCreation) {
result.append("array("); //$NON-NLS-1$
ArrayElement[] elements = arrayCreation.getElements();
for (int i = 0; i < elements.length; i++) {
elements[i].accept(this);
result.append(","); //$NON-NLS-1$
}
result.append(")"); //$NON-NLS-1$
return false;
}
public boolean visit(ArrayElement arrayElement) {
if (arrayElement.getKey() != null) {
arrayElement.getKey().accept(this);
result.append("=>"); //$NON-NLS-1$
}
arrayElement.getValue().accept(this);
return false;
}
public boolean visit(Assignment assignment) {
assignment.getLeftHandSide().accept(this);
result.append(Assignment.getOperator(assignment.getOperator()));
assignment.getRightHandSide().accept(this);
return false;
}
public boolean visit(ASTError astError) {
// cant flatten, needs source
return false;
}
public boolean visit(BackTickExpression backTickExpression) {
result.append("`"); //$NON-NLS-1$
Expression[] expressions = backTickExpression.getExpressions();
for (int i = 0; i < expressions.length; i++) {
expressions[i].accept(this);
}
result.append("`"); //$NON-NLS-1$
return false;
}
public boolean visit(Block block) {
if (block.isCurly()) {
result.append("{\n"); //$NON-NLS-1$
} else {
result.append(":\n"); //$NON-NLS-1$
}
visitList(block, Block.STATEMENTS_PROPERTY, null);
if (block.isCurly()) {
result.append("}\n"); //$NON-NLS-1$
} else {
StructuralPropertyDescriptor locationInParent = block
.getLocationInParent();
if (locationInParent == IfStatement.TRUE_STATEMENT_PROPERTY) {
if (((IfStatement) block.getParent()).getFalseStatement() == null) {
// End the if statement
result.append("endif;\n"); //$NON-NLS-1$
} else {
// Just add a new line char
result.append("\n"); //$NON-NLS-1$
}
} else if (locationInParent == IfStatement.FALSE_STATEMENT_PROPERTY) {
result.append("endif;\n"); //$NON-NLS-1$
} else if (locationInParent == WhileStatement.BODY_PROPERTY) {
result.append("endwhile;\n"); //$NON-NLS-1$
} else if (locationInParent == ForStatement.BODY_PROPERTY) {
result.append("endfor;\n"); //$NON-NLS-1$
} else if (locationInParent == ForEachStatement.STATEMENT_PROPERTY) {
result.append("endforeach;\n"); //$NON-NLS-1$
} else if (locationInParent == SwitchStatement.BODY_PROPERTY) {
result.append("endswitch;\n"); //$NON-NLS-1$
}
}
return false;
}
public boolean visit(BreakStatement breakStatement) {
result.append("break"); //$NON-NLS-1$
if (breakStatement.getExpr() != null) {
result.append(' ');
breakStatement.getExpr().accept(this);
}
result.append(";\n"); //$NON-NLS-1$
return false;
}
public boolean visit(CastExpression castExpression) {
result.append("("); //$NON-NLS-1$
result.append(CastExpression.getCastType(castExpression.getCastType()));
result.append(")"); //$NON-NLS-1$
castExpression.getExpr().accept(this);
return false;
}
public boolean visit(CatchClause catchClause) {
result.append("catch ("); //$NON-NLS-1$
catchClause.getClassName().accept(this);
result.append(" "); //$NON-NLS-1$
catchClause.getVariable().accept(this);
result.append(") "); //$NON-NLS-1$
catchClause.getStatement().accept(this);
return false;
}
public boolean visit(ConstantDeclaration classConstantDeclaration) {
result.append("const "); //$NON-NLS-1$
boolean isFirst = true;
Identifier[] variableNames = classConstantDeclaration
.getVariableNames();
Expression[] constantValues = classConstantDeclaration
.getConstantValues();
for (int i = 0; i < variableNames.length; i++) {
if (!isFirst) {
result.append(", "); //$NON-NLS-1$
}
variableNames[i].accept(this);
result.append(" = "); //$NON-NLS-1$
constantValues[i].accept(this);
isFirst = false;
}
result.append(";\n"); //$NON-NLS-1$
return false;
}
public boolean visit(ClassDeclaration classDeclaration) {
int modifier = classDeclaration.getModifier();
if (modifier != ClassDeclaration.MODIFIER_NONE) {
result.append(ClassDeclaration.getModifier(modifier));
result.append(' ');
}
result.append("class "); //$NON-NLS-1$
classDeclaration.getName().accept(this);
if (classDeclaration.getSuperClass() != null) {
result.append(" extends "); //$NON-NLS-1$
classDeclaration.getSuperClass().accept(this);
}
Identifier[] interfaces = classDeclaration.getInterfaces();
if (interfaces != null && interfaces.length != 0) {
result.append(" implements "); //$NON-NLS-1$
interfaces[0].accept(this);
for (int i = 1; i < interfaces.length; i++) {
result.append(" , "); //$NON-NLS-1$
interfaces[i].accept(this);
}
}
classDeclaration.getBody().accept(this);
return false;
}
public boolean visit(ClassInstanceCreation classInstanceCreation) {
result.append("new "); //$NON-NLS-1$
classInstanceCreation.getClassName().accept(this);
Expression[] ctorParams = classInstanceCreation.getCtorParams();
if (ctorParams.length != 0) {
result.append("("); //$NON-NLS-1$
ctorParams[0].accept(this);
for (int i = 1; i < ctorParams.length; i++) {
result.append(","); //$NON-NLS-1$
ctorParams[i].accept(this);
}
result.append(")"); //$NON-NLS-1$
}
return false;
}
public boolean visit(ClassName className) {
className.getClassName().accept(this);
return false;
}
public boolean visit(CloneExpression cloneExpression) {
result.append("clone "); //$NON-NLS-1$
cloneExpression.getExpr().accept(this);
return false;
}
public boolean visit(Comment comment) {
result.append(getComment(comment));
result.append("\n");
return false;
}
public String getComment(Comment comment) {
if (comment.getCommentType() == Comment.TYPE_SINGLE_LINE) {
return "//";
}
if (comment.getCommentType() == Comment.TYPE_MULTILINE) {
return "/* */";
}
if (comment.getCommentType() == Comment.TYPE_PHPDOC) {
return "/** */"; //$NON-NLS-1$"
}
return null;
}
public boolean visit(ConditionalExpression conditionalExpression) {
conditionalExpression.getCondition().accept(this);
result.append(" ? "); //$NON-NLS-1$
conditionalExpression.getIfTrue().accept(this);
result.append(" : "); //$NON-NLS-1$
conditionalExpression.getIfFalse().accept(this);
return false;
}
public boolean visit(ContinueStatement continueStatement) {
result.append("continue "); //$NON-NLS-1$
if (continueStatement.getExpr() != null) {
continueStatement.getExpr().accept(this);
}
result.append(";\n"); //$NON-NLS-1$
return false;
}
public boolean visit(DeclareStatement declareStatement) {
result.append("declare ("); //$NON-NLS-1$
boolean isFirst = true;
Identifier[] directiveNames = declareStatement.getDirectiveNames();
Expression[] directiveValues = declareStatement.getDirectiveValues();
for (int i = 0; i < directiveNames.length; i++) {
if (!isFirst) {
result.append(", "); //$NON-NLS-1$
}
directiveNames[i].accept(this);
result.append(" = "); //$NON-NLS-1$
directiveValues[i].accept(this);
isFirst = false;
}
result.append(")"); //$NON-NLS-1$
declareStatement.getAction().accept(this);
return false;
}
public boolean visit(DoStatement doStatement) {
result.append("do "); //$NON-NLS-1$
Statement body = doStatement.getBody();
if (body != null) {
body.accept(this);
}
result.append("while ("); //$NON-NLS-1$
Expression cond = doStatement.getCondition();
if (cond != null) {
cond.accept(this);
}
result.append(");\n"); //$NON-NLS-1$
return false;
}
public boolean visit(EchoStatement echoStatement) {
result.append("echo "); //$NON-NLS-1$
List<Expression> expressions = echoStatement.expressions();
for (int i = 0; i < expressions.size(); i++) {
expressions.get(i).accept(this);
if (i + 1 < expressions.size()) {
result.append(", ");
}
}
result.append(";\n"); //$NON-NLS-1$
return false;
}
public boolean visit(EmptyStatement emptyStatement) {
result.append(";\n"); //$NON-NLS-1$
return false;
}
public boolean visit(ExpressionStatement expressionStatement) {
if (expressionStatement.getExpression() != null) {
expressionStatement.getExpression().accept(this);
result.append(";\n"); //$NON-NLS-1$
} else {
result.append("Missing();");
}
return false;
}
public boolean visit(FieldAccess fieldAccess) {
fieldAccess.getDispatcher().accept(this);
result.append("->"); //$NON-NLS-1$
fieldAccess.getField().accept(this);
return false;
}
public boolean visit(FieldsDeclaration fieldsDeclaration) {
Variable[] variableNames = fieldsDeclaration.getVariableNames();
Expression[] initialValues = fieldsDeclaration.getInitialValues();
for (int i = 0; i < variableNames.length; i++) {
result.append(fieldsDeclaration.getModifierString() + " "); //$NON-NLS-1$
variableNames[i].accept(this);
if (initialValues[i] != null) {
result.append(" = "); //$NON-NLS-1$
initialValues[i].accept(this);
}
result.append(";\n"); //$NON-NLS-1$
}
return false;
}
public boolean visit(ForEachStatement forEachStatement) {
result.append("foreach ("); //$NON-NLS-1$
Expression express = forEachStatement.getExpression();
if (express != null) {
express.accept(this);
}
result.append(" as "); //$NON-NLS-1$
if (forEachStatement.getKey() != null) {
forEachStatement.getKey().accept(this);
result.append(" => "); //$NON-NLS-1$
}
Expression value = forEachStatement.getValue();
if (value != null) {
value.accept(this);
}
result.append(")"); //$NON-NLS-1$
forEachStatement.getStatement().accept(this);
return false;
}
public boolean visit(NamespaceDeclaration namespaceDeclaration) {
result.append("namespace ");
namespaceDeclaration.childrenAccept(this);
if (namespaceDeclaration.getBody() == null) {
result.append(";\n"); //$NON-NLS-1$
}
return false;
}
public boolean visit(NamespaceName namespaceName) {
if (namespaceName.isGlobal()) {
result.append("\\");
}
if (namespaceName.isCurrent()) {
result.append("namespace\\");
}
List<Identifier> segments = namespaceName.segments();
Iterator<Identifier> it = segments.iterator();
while (it.hasNext()) {
it.next().accept(this);
if (it.hasNext()) {
result.append("\\");
}
}
return false;
}
public boolean visit(UseStatement useStatement) {
result.append("use ");
Iterator<UseStatementPart> it = useStatement.parts().iterator();
while (it.hasNext()) {
it.next().accept(this);
if (it.hasNext()) {
result.append(", ");
}
}
result.append(";\n");
return false;
}
public boolean visit(UseStatementPart useStatementPart) {
useStatementPart.getName().accept(this);
Identifier alias = useStatementPart.getAlias();
if (alias != null) {
result.append(" as ");
alias.accept(this);
}
return false;
}
public boolean visit(FormalParameter formalParameter) {
if (formalParameter.isMandatory()) {
if (formalParameter.getAST().apiLevel() == PHPVersion.PHP4) {
result.append("const "); // only for PHP 4
}
}
Expression paramType = formalParameter.getParameterType();
if (paramType != null /* && paramType.getLength() > 0 */) {
paramType.accept(this);
result.append(' ');
}
formalParameter.getParameterName().accept(this);
Expression defaultValue = formalParameter.getDefaultValue();
if (defaultValue != null /* && defaultValue.getLength() > 0 */) {
result.append(" = ");
defaultValue.accept(this);
}
return false;
}
public boolean visit(ForStatement forStatement) {
boolean isFirst = true;
result.append("for ("); //$NON-NLS-1$
Expression[] initializations = forStatement.getInitializations();
Expression[] conditions = forStatement.getConditions();
Expression[] increasements = forStatement.getIncreasements();
for (int i = 0; i < initializations.length; i++) {
if (!isFirst) {
result.append(", "); //$NON-NLS-1$
}
initializations[i].accept(this);
isFirst = false;
}
isFirst = true;
result.append(" ; "); //$NON-NLS-1$
for (int i = 0; i < conditions.length; i++) {
if (!isFirst) {
result.append(", "); //$NON-NLS-1$
}
conditions[i].accept(this);
isFirst = false;
}
isFirst = true;
result.append(" ; "); //$NON-NLS-1$
for (int i = 0; i < increasements.length; i++) {
if (!isFirst) {
result.append(", "); //$NON-NLS-1$
}
increasements[i].accept(this);
isFirst = false;
}
result.append(" ) "); //$NON-NLS-1$
Statement body = forStatement.getBody();
if (body != null) {
body.accept(this);
}
return false;
}
public boolean visit(FunctionDeclaration functionDeclaration) {
result.append(" function ");
if (functionDeclaration.isReference()) {
result.append('&');
}
functionDeclaration.getFunctionName().accept(this);
result.append('(');
List<FormalParameter> formalParametersList = functionDeclaration
.formalParameters();
FormalParameter[] formalParameters = formalParametersList
.toArray(new FormalParameter[formalParametersList.size()]);
if (formalParameters.length != 0) {
formalParameters[0].accept(this);
for (int i = 1; i < formalParameters.length; i++) {
result.append(", "); //$NON-NLS-1$
formalParameters[i].accept(this);
}
}
result.append(')');
Block body = functionDeclaration.getBody();
if (body != null) {
body.accept(this);
}
return false;
}
public boolean visit(FunctionInvocation functionInvocation) {
functionInvocation.getFunctionName().accept(this);
result.append('(');
Expression[] parameters = functionInvocation.getParameters();
if (parameters.length != 0) {
parameters[0].accept(this);
for (int i = 1; i < parameters.length; i++) {
result.append(',');
parameters[i].accept(this);
}
}
result.append(')');
return false;
}
public boolean visit(FunctionName functionName) {
functionName.getFunctionName().accept(this);
return false;
}
public boolean visit(GlobalStatement globalStatement) {
result.append("global "); //$NON-NLS-1$
boolean isFirst = true;
Variable[] variables = globalStatement.getVariables();
for (int i = 0; i < variables.length; i++) {
if (!isFirst) {
result.append(", "); //$NON-NLS-1$
}
variables[i].accept(this);
isFirst = false;
}
result.append(";\n "); //$NON-NLS-1$
return false;
}
public boolean visit(GotoLabel gotoLabel) {
gotoLabel.getName().accept(this);
result.append(":\n "); //$NON-NLS-1$
return false;
}
public boolean visit(GotoStatement gotoStatement) {
result.append("goto "); //$NON-NLS-1$
gotoStatement.getLabel().accept(this);
result.append(";\n "); //$NON-NLS-1$
return false;
}
public boolean visit(Identifier identifier) {
result.append(identifier.getName());
return false;
}
public boolean visit(IfStatement ifStatement) {
result.append("if("); //$NON-NLS-1$
Expression cond = ifStatement.getCondition();
if (cond != null) {
cond.accept(this);
}
result.append(")"); //$NON-NLS-1$
Statement trueStatement = ifStatement.getTrueStatement();
if (trueStatement != null) {
trueStatement.accept(this);
}
if (ifStatement.getFalseStatement() != null) {
result.append("else"); //$NON-NLS-1$
ifStatement.getFalseStatement().accept(this);
}
return false;
}
public boolean visit(IgnoreError ignoreError) {
result.append("@"); //$NON-NLS-1$
ignoreError.getExpr().accept(this);
return false;
}
public boolean visit(Include include) {
result.append(Include.getType(include.getIncludeType()));
result.append(" ("); //$NON-NLS-1$
include.getExpr().accept(this);
result.append(")"); //$NON-NLS-1$
return false;
}
public boolean visit(InfixExpression infixExpression) {
infixExpression.getLeft().accept(this);
result.append(' ');
result.append(InfixExpression
.getOperator(infixExpression.getOperator()));
result.append(' ');
infixExpression.getRight().accept(this);
return false;
}
public boolean visit(InLineHtml inLineHtml) {
// cant flatten, needs source
return false;
}
public boolean visit(InstanceOfExpression instanceOfExpression) {
instanceOfExpression.getExpr().accept(this);
result.append(" instanceof "); //$NON-NLS-1$
instanceOfExpression.getClassName().accept(this);
return false;
}
public boolean visit(InterfaceDeclaration interfaceDeclaration) {
result.append("interface "); //$NON-NLS-1$
interfaceDeclaration.getName().accept(this);
result.append(" extends "); //$NON-NLS-1$
boolean isFirst = true;
Identifier[] interfaces = interfaceDeclaration.getInterfaces();
for (int i = 0; interfaces != null && i < interfaces.length; i++) {
if (!isFirst) {
result.append(", "); //$NON-NLS-1$
}
interfaces[i].accept(this);
isFirst = false;
}
interfaceDeclaration.getBody().accept(this);
return false;
}
public boolean visit(ListVariable listVariable) {
result.append("list("); //$NON-NLS-1$
boolean isFirst = true;
VariableBase[] variables = listVariable.getVariables();
for (int i = 0; i < variables.length; i++) {
if (!isFirst) {
result.append(", "); //$NON-NLS-1$
}
variables[i].accept(this);
isFirst = false;
}
result.append(")"); //$NON-NLS-1$
return false;
}
public boolean visit(LambdaFunctionDeclaration functionDeclaration) {
result.append(" function ");
if (functionDeclaration.isReference()) {
result.append('&');
}
result.append('(');
List<FormalParameter> formalParametersList = functionDeclaration
.formalParameters();
Iterator<FormalParameter> paramIt = formalParametersList.iterator();
while (paramIt.hasNext()) {
paramIt.next().accept(this);
if (paramIt.hasNext()) {
result.append(", ");
}
}
result.append(')');
List<Expression> lexicalVariables = functionDeclaration
.lexicalVariables();
if (lexicalVariables.size() > 0) {
result.append(" use (");
Iterator<Expression> it = lexicalVariables.iterator();
while (it.hasNext()) {
it.next().accept(this);
if (it.hasNext()) {
result.append(", "); //$NON-NLS-1$
}
}
result.append(')');
}
if (functionDeclaration.getBody() != null) {
functionDeclaration.getBody().accept(this);
}
return false;
}
public boolean visit(MethodDeclaration methodDeclaration) {
Comment comment = methodDeclaration.getComment();
if (comment != null) {
comment.accept(this);
}
result.append(methodDeclaration.getModifierString());
methodDeclaration.getFunction().accept(this);
return false;
}
public boolean visit(MethodInvocation methodInvocation) {
methodInvocation.getDispatcher().accept(this);
result.append("->"); //$NON-NLS-1$
methodInvocation.getMethod().accept(this);
return false;
}
public boolean visit(ParenthesisExpression parenthesisExpression) {
result.append("("); //$NON-NLS-1$
if (parenthesisExpression.getExpr() != null) {
parenthesisExpression.getExpr().accept(this);
}
result.append(")"); //$NON-NLS-1$
return false;
}
public boolean visit(PostfixExpression postfixExpressions) {
postfixExpressions.getVariable().accept(this);
result.append(PostfixExpression.getOperator(postfixExpressions
.getOperator()));
return false;
}
public boolean visit(PrefixExpression prefixExpression) {
prefixExpression.getVariable().accept(this);
result.append(PrefixExpression.getOperator(prefixExpression
.getOperator()));
return false;
}
public boolean visit(Program program) {
boolean isPhpState = false;
Statement[] statements = program.getStatements();
for (int i = 0; i < statements.length; i++) {
boolean isHtml = statements[i] instanceof InLineHtml;
if (!isHtml && !isPhpState) {
// html -> php
result.append("<?php\n"); //$NON-NLS-1$
statements[i].accept(this);
isPhpState = true;
} else if (!isHtml && isPhpState) {
// php -> php
statements[i].accept(this);
result.append("\n"); //$NON-NLS-1$
} else if (isHtml && isPhpState) {
// php -> html
result.append("?>\n"); //$NON-NLS-1$
statements[i].accept(this);
result.append("\n"); //$NON-NLS-1$
isPhpState = false;
} else {
// html first
statements[i].accept(this);
result.append("\n"); //$NON-NLS-1$
}
}
if (isPhpState) {
result.append("?>\n"); //$NON-NLS-1$
}
Collection comments = program.getComments();
for (Iterator iter = comments.iterator(); iter.hasNext();) {
Comment comment = (Comment) iter.next();
comment.accept(this);
}
return false;
}
public boolean visit(Quote quote) {
switch (quote.getQuoteType()) {
case 0:
result.append("\""); //$NON-NLS-1$
acceptQuoteExpression(quote.getExpressions());
result.append("\""); //$NON-NLS-1$
break;
case 1:
result.append("\'"); //$NON-NLS-1$
acceptQuoteExpression(quote.getExpressions());
result.append("\'"); //$NON-NLS-1$
break;
case 2:
result.append("<<<Heredoc\n"); //$NON-NLS-1$
acceptQuoteExpression(quote.getExpressions());
result.append("\nHeredoc"); //$NON-NLS-1$
}
return false;
}
public boolean visit(Reference reference) {
result.append("&"); //$NON-NLS-1$
reference.getExpression().accept(this);
return false;
}
public boolean visit(ReflectionVariable reflectionVariable) {
result.append("$"); //$NON-NLS-1$
reflectionVariable.getVariableName().accept(this);
return false;
}
public boolean visit(ReturnStatement returnStatement) {
result.append("return "); //$NON-NLS-1$
if (returnStatement.getExpr() != null) {
returnStatement.getExpr().accept(this);
}
result.append(";\n"); //$NON-NLS-1$
return false;
}
public boolean visit(Scalar scalar) {
if (scalar.getScalarType() == Scalar.TYPE_UNKNOWN) {
// cant flatten, needs source
} else {
result.append(scalar.getStringValue());
}
return false;
}
public boolean visit(StaticConstantAccess staticFieldAccess) {
staticFieldAccess.getClassName().accept(this);
result.append("::"); //$NON-NLS-1$
staticFieldAccess.getConstant().accept(this);
return false;
}
public boolean visit(StaticFieldAccess staticFieldAccess) {
staticFieldAccess.getClassName().accept(this);
result.append("::"); //$NON-NLS-1$
staticFieldAccess.getField().accept(this);
return false;
}
public boolean visit(StaticMethodInvocation staticMethodInvocation) {
staticMethodInvocation.getClassName().accept(this);
result.append("::"); //$NON-NLS-1$
staticMethodInvocation.getMethod().accept(this);
return false;
}
public boolean visit(StaticStatement staticStatement) {
result.append("static "); //$NON-NLS-1$
boolean isFirst = true;
Expression[] expressions = staticStatement.getExpressions();
for (int i = 0; i < expressions.length; i++) {
if (!isFirst) {
result.append(", "); //$NON-NLS-1$
}
expressions[i].accept(this);
isFirst = false;
}
result.append(";\n"); //$NON-NLS-1$
return false;
}
public boolean visit(SwitchCase switchCase) {
if (switchCase.isDefault()) {
result.append("default:\n");
} else {
result.append("case ");
if (switchCase.getValue() != null) {
switchCase.getValue().accept(this);
result.append(":\n"); //$NON-NLS-1$
}
}
Statement[] actions = switchCase.getActions();
for (int i = 0; i < actions.length; i++) {
actions[i].accept(this);
}
return false;
}
public boolean visit(SwitchStatement switchStatement) {
result.append("switch ("); //$NON-NLS-1$
Expression express = switchStatement.getExpression();
if (express != null) {
express.accept(this);
}
result.append(")"); //$NON-NLS-1$
Block statment = switchStatement.getBody();
if (statment != null) {
statment.accept(this);
}
return false;
}
public boolean visit(ThrowStatement throwStatement) {
throwStatement.getExpression().accept(this);
return false;
}
public boolean visit(TryStatement tryStatement) {
result.append("try "); //$NON-NLS-1$
Block body = tryStatement.getBody();
if (body != null) {
body.accept(this);
}
List<CatchClause> catchClauses = tryStatement.catchClauses();
for (int i = 0; i < catchClauses.size(); i++) {
catchClauses.get(i).accept(this);
}
return false;
}
public boolean visit(UnaryOperation unaryOperation) {
result.append(UnaryOperation.getOperator(unaryOperation.getOperator()));
unaryOperation.getExpression().accept(this);
return false;
}
public boolean visit(Variable variable) {
if (variable.isDollared()) {
result.append("$");
}
variable.getName().accept(this);
return false;
}
public boolean visit(WhileStatement whileStatement) {
result.append("while ("); //$NON-NLS-1$
Expression condition = whileStatement.getCondition();
if (condition != null) {
whileStatement.getCondition().accept(this);
}
result.append(")\n"); //$NON-NLS-1$
Statement body = whileStatement.getBody();
if (body != null) {
body.accept(this);
}
return false;
}
public boolean visit(SingleFieldDeclaration singleFieldDeclaration) {
singleFieldDeclaration.getName().accept(this);
Expression value = singleFieldDeclaration.getValue();
if (value != null) {
result.append(" = ");//$NON-NLS-1$
value.accept(this);
}
return false;
}
private void acceptQuoteExpression(Expression[] expressions) {
for (int i = 0; i < expressions.length; i++) {
expressions[i].accept(this);
}
}
}