1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
12 package net.sourceforge.phpdt.core.dom;
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
20 * Postfix expression AST node type.
24 * Expression PostfixOperator
28 * @noinstantiate This class is not intended to be instantiated by clients.
30 public class PostfixExpression extends Expression {
33 * Postfix operators (typesafe enumeration).
36 * <b><code>++</code></b> <code>INCREMENT</code>
37 * <b><code>--</code></b> <code>DECREMENT</code>
40 public static class Operator {
43 * The token for the operator.
48 * Creates a new postfix operator with the given token.
50 * Note: this constructor is private. The only instances
51 * ever created are the ones for the standard operators.
54 * @param token the character sequence for the operator
56 private Operator(String token) {
61 * Returns the character sequence for the operator.
63 * @return the character sequence for the operator
65 public String toString() {
69 /** Postfix increment "++" operator. */
70 public static final Operator INCREMENT = new Operator("++");//$NON-NLS-1$
71 /** Postfix decrement "--" operator. */
72 public static final Operator DECREMENT = new Operator("--");//$NON-NLS-1$
75 * Map from token to operator (key type: <code>String</code>;
76 * value type: <code>Operator</code>).
78 private static final Map CODES;
80 CODES = new HashMap(20);
85 for (int i = 0; i < ops.length; i++) {
86 CODES.put(ops[i].toString(), ops[i]);
91 * Returns the postfix operator corresponding to the given string,
92 * or <code>null</code> if none.
94 * <code>toOperator</code> is the converse of <code>toString</code>:
95 * that is, <code>Operator.toOperator(op.toString()) == op</code> for
96 * all operators <code>op</code>.
99 * @param token the character sequence for the operator
100 * @return the postfix operator, or <code>null</code> if none
102 public static Operator toOperator(String token) {
103 return (Operator) CODES.get(token);
108 * The "operator" structural property of this node type.
111 public static final SimplePropertyDescriptor OPERATOR_PROPERTY =
112 new SimplePropertyDescriptor(PostfixExpression.class, "operator", PostfixExpression.Operator.class, MANDATORY); //$NON-NLS-1$
115 * The "operand" structural property of this node type.
118 public static final ChildPropertyDescriptor OPERAND_PROPERTY =
119 new ChildPropertyDescriptor(PostfixExpression.class, "operand", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
122 * A list of property descriptors (element type:
123 * {@link StructuralPropertyDescriptor}),
124 * or null if uninitialized.
126 private static final List PROPERTY_DESCRIPTORS;
129 List propertyList = new ArrayList(3);
130 createPropertyList(PostfixExpression.class, propertyList);
131 addProperty(OPERAND_PROPERTY, propertyList);
132 addProperty(OPERATOR_PROPERTY, propertyList);
133 PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
137 * Returns a list of structural property descriptors for this node type.
138 * Clients must not modify the result.
140 * @param apiLevel the API level; one of the
141 * <code>AST.JLS*</code> constants
143 * @return a list of property descriptors (element type:
144 * {@link StructuralPropertyDescriptor})
147 public static List propertyDescriptors(int apiLevel) {
148 return PROPERTY_DESCRIPTORS;
152 * The operator; defaults to an unspecified postfix operator.
154 private PostfixExpression.Operator operator =
155 PostfixExpression.Operator.INCREMENT;
158 * The operand; lazily initialized; defaults to an unspecified,
159 * but legal, simple name.
161 private Expression operand = null;
164 * Creates a new AST node for an postfix expression owned by the given
165 * AST. By default, the node has unspecified (but legal) operator and
168 * @param ast the AST that is to own this node
170 PostfixExpression(AST ast) {
174 /* (omit javadoc for this method)
175 * Method declared on ASTNode.
177 final List internalStructuralPropertiesForType(int apiLevel) {
178 return propertyDescriptors(apiLevel);
181 /* (omit javadoc for this method)
182 * Method declared on ASTNode.
184 final Object internalGetSetObjectProperty(SimplePropertyDescriptor property, boolean get, Object value) {
185 if (property == OPERATOR_PROPERTY) {
187 return getOperator();
189 setOperator((Operator) value);
193 // allow default implementation to flag the error
194 return super.internalGetSetObjectProperty(property, get, value);
197 /* (omit javadoc for this method)
198 * Method declared on ASTNode.
200 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
201 if (property == OPERAND_PROPERTY) {
205 setOperand((Expression) child);
209 // allow default implementation to flag the error
210 return super.internalGetSetChildProperty(property, get, child);
213 /* (omit javadoc for this method)
214 * Method declared on ASTNode.
216 final int getNodeType0() {
217 return POSTFIX_EXPRESSION;
220 /* (omit javadoc for this method)
221 * Method declared on ASTNode.
223 ASTNode clone0(AST target) {
224 PostfixExpression result = new PostfixExpression(target);
225 result.setSourceRange(this.getStartPosition(), this.getLength());
226 result.setOperator(getOperator());
227 result.setOperand((Expression) getOperand().clone(target));
231 /* (omit javadoc for this method)
232 * Method declared on ASTNode.
234 final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
235 // dispatch to correct overloaded match method
236 return matcher.match(this, other);
239 /* (omit javadoc for this method)
240 * Method declared on ASTNode.
242 void accept0(ASTVisitor visitor) {
243 boolean visitChildren = visitor.visit(this);
245 acceptChild(visitor, getOperand());
247 visitor.endVisit(this);
251 * Returns the operator of this postfix expression.
253 * @return the operator
255 public PostfixExpression.Operator getOperator() {
256 return this.operator;
260 * Sets the operator of this postfix expression.
262 * @param operator the operator
263 * @exception IllegalArgumentException if the argument is incorrect
265 public void setOperator(PostfixExpression.Operator operator) {
266 if (operator == null) {
267 throw new IllegalArgumentException();
269 preValueChange(OPERATOR_PROPERTY);
270 this.operator = operator;
271 postValueChange(OPERATOR_PROPERTY);
275 * Returns the operand of this postfix expression.
277 * @return the operand expression node
279 public Expression getOperand() {
280 if (this.operand == null) {
281 // lazy init must be thread-safe for readers
282 synchronized (this) {
283 if (this.operand == null) {
285 this.operand= new SimpleName(this.ast);
286 postLazyInit(this.operand, OPERAND_PROPERTY);
294 * Sets the operand of this postfix expression.
296 * @param expression the operand expression node
297 * @exception IllegalArgumentException if:
299 * <li>the node belongs to a different AST</li>
300 * <li>the node already has a parent</li>
301 * <li>a cycle in would be created</li>
304 public void setOperand(Expression expression) {
305 if (expression == null) {
306 throw new IllegalArgumentException();
308 ASTNode oldChild = this.operand;
309 preReplaceChild(oldChild, expression, OPERAND_PROPERTY);
310 this.operand = expression;
311 postReplaceChild(oldChild, expression, OPERAND_PROPERTY);
314 /* (omit javadoc for this method)
315 * Method declared on ASTNode.
318 // treat Operator as free
319 return BASE_NODE_SIZE + 2 * 4;
322 /* (omit javadoc for this method)
323 * Method declared on ASTNode.
328 + (this.operand == null ? 0 : getOperand().treeSize());