/*******************************************************************************
* 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.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;
import org2.eclipse.php.internal.core.ast.nodes.*;
import org2.eclipse.php.internal.core.ast.rewrite.RewriteEventStore.CopySourceInfo;
/**
*
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public final class NodeInfoStore {
private AST ast;
private Map placeholderNodes;
private Set collapsedNodes;
public NodeInfoStore(AST ast) {
super();
this.ast = ast;
this.placeholderNodes = null;
this.collapsedNodes = null;
}
/**
* Marks a node as a placehoder for a plain string content. The type of the
* node should correspond to the code's code content.
*
* @param placeholder
* The placeholder node that acts for the string content.
* @param code
* The string content.
*/
public final void markAsStringPlaceholder(ASTNode placeholder, String code) {
StringPlaceholderData data = new StringPlaceholderData();
data.code = code;
setPlaceholderData(placeholder, data);
}
/**
* Marks a node as a copy or move target. The copy target represents a
* copied node at the target (copied) site.
*
* @param target
* The node at the target site. Can be a placeholder node but
* also the source node itself.
* @param copySource
* The info at the source site.
*/
public final void markAsCopyTarget(ASTNode target, CopySourceInfo copySource) {
CopyPlaceholderData data = new CopyPlaceholderData();
data.copySource = copySource;
setPlaceholderData(target, data);
}
/**
* Creates a placeholder node of the given type. <code>null</code> if the
* type is not supported
*
* @param nodeType
* Type of the node to create. Use the type constants in
* {@link NodeInfoStore}.
* @return Returns a place holder node.
*/
@SuppressWarnings("nls")
public final ASTNode newPlaceholderNode(int nodeType) {
try {
ASTNode node = this.ast.createInstance(nodeType);
switch (node.getType()) {
case ASTNode.ASSIGNMENT:
Assignment assignment = (Assignment) node;
assignment.setLeftHandSide(this.ast.newVariable("a"));
assignment.setOperator(Assignment.OP_EQUAL);
assignment.setRightHandSide(this.ast.newVariable("a"));
break;
case ASTNode.INFIX_EXPRESSION:
InfixExpression expression = (InfixExpression) node;
expression.setLeft(this.ast.newScalar("a"));
expression.setOperator(InfixExpression.OP_MINUS);
expression.setRight(this.ast.newVariable("a"));
break;
case ASTNode.VARIABLE:
Variable variable = (Variable) node;
variable.setName(this.ast.newIdentifier(""));
break;
case ASTNode.FOR_STATEMENT:
ForStatement forStatement = (ForStatement) node;
Assignment assignment1 = this.ast.newAssignment();
assignment1.setLeftHandSide(this.ast.newVariable("a"));
assignment1.setOperator(Assignment.OP_EQUAL);
assignment1.setRightHandSide(this.ast.newVariable("a"));
forStatement.initializers().add(assignment1);
InfixExpression expression1 = this.ast.newInfixExpression();
expression1.setLeft(this.ast.newScalar("a"));
expression1.setOperator(InfixExpression.OP_IS_NOT_EQUAL);
expression1.setRight(this.ast.newVariable("a"));
forStatement.conditions().add(expression1);
PostfixExpression pexp = this.ast.newPostfixExpression();
pexp.setOperator(PostfixExpression.OP_INC);
pexp.setVariable(this.ast.newVariable("a"));
forStatement.updaters().add(pexp);
forStatement.setBody(this.ast.newBlock());
break;
}
return node;
} catch (IllegalArgumentException e) {
return null;
}
}
// collapsed nodes: in source: use one node that represents many; to be used
// as
// copy/move source or to replace at once.
// in the target: one block node that is not flattened.
public Block createCollapsePlaceholder() {
Block placeHolder = this.ast.newBlock();
if (this.collapsedNodes == null) {
this.collapsedNodes = new HashSet();
}
this.collapsedNodes.add(placeHolder);
return placeHolder;
}
public boolean isCollapsed(ASTNode node) {
if (this.collapsedNodes != null) {
return this.collapsedNodes.contains(node);
}
return false;
}
public Object getPlaceholderData(ASTNode node) {
if (this.placeholderNodes != null) {
return this.placeholderNodes.get(node);
}
return null;
}
private void setPlaceholderData(ASTNode node, PlaceholderData data) {
if (this.placeholderNodes == null) {
this.placeholderNodes = new IdentityHashMap();
}
this.placeholderNodes.put(node, data);
}
static class PlaceholderData {
// base class
}
protected static final class CopyPlaceholderData extends PlaceholderData {
public CopySourceInfo copySource;
public String toString() {
return "[placeholder " + this.copySource + "]"; //$NON-NLS-1$//$NON-NLS-2$
}
}
protected static final class StringPlaceholderData extends PlaceholderData {
public String code;
public String toString() {
return "[placeholder string: " + this.code + "]"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
/**
*
*/
public void clear() {
this.placeholderNodes = null;
this.collapsedNodes = null;
}
}