/*******************************************************************************
* 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.corext;
import org.eclipse.core.runtime.Assert;
import org2.eclipse.dltk.ast.Modifiers;
import org2.eclipse.php.internal.core.ast.nodes.*;
import org2.eclipse.php.internal.core.ast.rewrite.ASTRewriteFlattener;
import org2.eclipse.php.internal.core.ast.visitor.ApplyAll;
public class ASTNodes {
public static final int NODE_ONLY = 0;
public static final int INCLUDE_FIRST_PARENT = 1;
public static final int INCLUDE_ALL_PARENTS = 2;
public static final int WARNING = 1 << 0;
public static final int ERROR = 1 << 1;
public static final int PROBLEMS = WARNING | ERROR;
private static final int CLEAR_VISIBILITY = ~(Modifiers.AccPublic
| Modifiers.AccProtected | Modifiers.AccPrivate);
private ASTNodes() {
// no instance;
}
public static String asString(ASTNode node) {
ASTRewriteFlattener flattener = new ASTRewriteFlattener(null);
node.accept(flattener);
return flattener.getResult();
}
public static String getQualifier(Identifier name) {
// if (name.isQualifiedName()) {
// return ((QualifiedName) name).getQualifier().getFullyQualifiedName();
// }
return ""; //$NON-NLS-1$
}
/**
* Returns true if a node at a given location is a body of a control
* statement. Such body nodes are interesting as when replacing them, it has
* to be evaluates if a Block is needed instead. E.g.
* <code> if (x) do(); -> if (x) { do1(); do2() } </code>
*
* @param locationInParent
* Location of the body node
* @return Returns true if the location is a body node location of a control
* statement.
*/
public static boolean isControlStatementBody(
StructuralPropertyDescriptor locationInParent) {
return locationInParent == IfStatement.TRUE_STATEMENT_PROPERTY
|| locationInParent == IfStatement.FALSE_STATEMENT_PROPERTY
|| locationInParent == ForStatement.BODY_PROPERTY
|| locationInParent == WhileStatement.BODY_PROPERTY
|| locationInParent == DoStatement.BODY_PROPERTY;
}
public static boolean needsParentheses(Expression expression) {
int type = expression.getType();
return type == ASTNode.INFIX_EXPRESSION
|| type == ASTNode.CONDITIONAL_EXPRESSION
|| type == ASTNode.PREFIX_EXPRESSION
|| type == ASTNode.POSTFIX_EXPRESSION
|| type == ASTNode.CAST_EXPRESSION
|| type == ASTNode.INSTANCE_OF_EXPRESSION;
}
@SuppressWarnings("rawtypes")
public static ASTNode getParent(ASTNode node, Class parentClass) {
do {
node = node.getParent();
} while (node != null && !parentClass.isInstance(node));
return node;
}
public static ASTNode getParent(ASTNode node, int nodeType) {
do {
node = node.getParent();
} while (node != null && node.getType() != nodeType);
return node;
}
public static ASTNode findParent(ASTNode node,
StructuralPropertyDescriptor[][] pathes) {
for (int p = 0; p < pathes.length; p++) {
StructuralPropertyDescriptor[] path = pathes[p];
ASTNode current = node;
int d = path.length - 1;
for (; d >= 0 && current != null; d--) {
StructuralPropertyDescriptor descriptor = path[d];
if (!descriptor.equals(current.getLocationInParent()))
break;
current = current.getParent();
}
if (d < 0)
return current;
}
return null;
}
public static boolean isParent(ASTNode node, ASTNode parent) {
Assert.isNotNull(parent);
do {
node = node.getParent();
if (node == parent)
return true;
} while (node != null);
return false;
}
public static int getExclusiveEnd(ASTNode node) {
return node.getStart() + node.getLength();
}
public static int getInclusiveEnd(ASTNode node) {
return node.getStart() + node.getLength() - 1;
}
@SuppressWarnings("unused")
private static int computeIterations(int flags) {
switch (flags) {
case NODE_ONLY:
return 1;
case INCLUDE_ALL_PARENTS:
return Integer.MAX_VALUE;
case INCLUDE_FIRST_PARENT:
return 2;
default:
return 1;
}
}
public static int changeVisibility(int modifiers, int visibility) {
return (modifiers & CLEAR_VISIBILITY) | visibility;
}
/**
* Adds flags to the given node and all its descendants.
*
* @param root
* The root node
* @param flags
* The flags to set
*/
public static void setFlagsToAST(ASTNode root, final int flags) {
if (root == null) {
return;
}
root.accept(new ApplyAll() {
protected boolean apply(ASTNode node) {
node.setFlags(node.getFlags() | flags);
return true;
}
});
}
}