EclipseJDT Source Viewer

Home|eclipse_jdt/src/org/eclipse/jdt/core/dom/PostfixExpression.java
1/*******************************************************************************
2 * Copyright (c) 2000, 2013 IBM Corporation and others.
3 *
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
8 *
9 * SPDX-License-Identifier: EPL-2.0
10 *
11 * Contributors:
12 *     IBM Corporation - initial API and implementation
13 *******************************************************************************/
14
15package org.eclipse.jdt.core.dom;
16
17import java.util.ArrayList;
18import java.util.HashMap;
19import java.util.List;
20import java.util.Map;
21
22/**
23 * Postfix expression AST node type.
24 *
25 * <pre>
26 * PostfixExpression:
27 *    Expression PostfixOperator
28 * </pre>
29 *
30 * @since 2.0
31 * @noinstantiate This class is not intended to be instantiated by clients.
32 */
33@SuppressWarnings({"rawtypes""unchecked"})
34public class PostfixExpression extends Expression {
35
36    /**
37      * Postfix operators (typesafe enumeration).
38     * <pre>
39     * PostfixOperator:
40     *    <b><code>++</code></b>  <code>INCREMENT</code>
41     *    <b><code>--</code></b>  <code>DECREMENT</code>
42     * </pre>
43     */
44    public static class Operator {
45
46        /**
47         * The token for the operator.
48         */
49        private String token;
50
51        /**
52         * Creates a new postfix operator with the given token.
53         * <p>
54         * Note: this constructor is private. The only instances
55         * ever created are the ones for the standard operators.
56         * </p>
57         *
58         * @param token the character sequence for the operator
59         */
60        private Operator(String token) {
61            this.token = token;
62        }
63
64        /**
65         * Returns the character sequence for the operator.
66         *
67         * @return the character sequence for the operator
68         */
69        @Override
70        public String toString() {
71            return this.token;
72        }
73
74        /** Postfix increment "++" operator. */
75        public static final Operator INCREMENT = new Operator("++");//$NON-NLS-1$
76        /** Postfix decrement "--" operator. */
77        public static final Operator DECREMENT = new Operator("--");//$NON-NLS-1$
78
79        /**
80         * Map from token to operator (key type: <code>String</code>;
81         * value type: <code>Operator</code>).
82         */
83        private static final Map CODES;
84        static {
85            CODES = new HashMap(20);
86            Operator[] ops = {
87                    INCREMENT,
88                    DECREMENT,
89                };
90            for (int i = 0i < ops.lengthi++) {
91                CODES.put(ops[i].toString(), ops[i]);
92            }
93        }
94
95        /**
96         * Returns the postfix operator corresponding to the given string,
97         * or <code>null</code> if none.
98         * <p>
99         * <code>toOperator</code> is the converse of <code>toString</code>:
100         * that is, <code>Operator.toOperator(op.toString()) == op</code> for
101         * all operators <code>op</code>.
102         * </p>
103         *
104         * @param token the character sequence for the operator
105         * @return the postfix operator, or <code>null</code> if none
106         */
107        public static Operator toOperator(String token) {
108            return (OperatorCODES.get(token);
109        }
110    }
111
112    /**
113     * The "operator" structural property of this node type (type: {@link PostfixExpression.Operator}).
114     * @since 3.0
115     */
116    public static final SimplePropertyDescriptor OPERATOR_PROPERTY =
117        new SimplePropertyDescriptor(PostfixExpression.class"operator"PostfixExpression.Operator.class, MANDATORY); //$NON-NLS-1$
118
119    /**
120     * The "operand" structural property of this node type (child type: {@link Expression}).
121     * @since 3.0
122     */
123    public static final ChildPropertyDescriptor OPERAND_PROPERTY =
124        new ChildPropertyDescriptor(PostfixExpression.class"operand"Expression.classMANDATORYCYCLE_RISK); //$NON-NLS-1$
125
126    /**
127     * A list of property descriptors (element type:
128     * {@link StructuralPropertyDescriptor}),
129     * or null if uninitialized.
130     */
131    private static final List PROPERTY_DESCRIPTORS;
132
133    static {
134        List propertyList = new ArrayList(3);
135        createPropertyList(PostfixExpression.classpropertyList);
136        addProperty(OPERAND_PROPERTYpropertyList);
137        addProperty(OPERATOR_PROPERTYpropertyList);
138        PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
139    }
140
141    /**
142     * Returns a list of structural property descriptors for this node type.
143     * Clients must not modify the result.
144     *
145     * @param apiLevel the API level; one of the
146     * <code>AST.JLS*</code> constants
147
148     * @return a list of property descriptors (element type:
149     * {@link StructuralPropertyDescriptor})
150     * @since 3.0
151     */
152    public static List propertyDescriptors(int apiLevel) {
153        return PROPERTY_DESCRIPTORS;
154    }
155
156    /**
157     * The operator; defaults to an unspecified postfix operator.
158     */
159    private PostfixExpression.Operator operator =
160        PostfixExpression.Operator.INCREMENT;
161
162    /**
163     * The operand; lazily initialized; defaults to an unspecified,
164     * but legal, simple name.
165     */
166    private Expression operand = null;
167
168    /**
169     * Creates a new AST node for an postfix expression owned by the given
170     * AST. By default, the node has unspecified (but legal) operator and
171     * operand.
172     *
173     * @param ast the AST that is to own this node
174     */
175    PostfixExpression(AST ast) {
176        super(ast);
177    }
178
179    @Override
180    final List internalStructuralPropertiesForType(int apiLevel) {
181        return propertyDescriptors(apiLevel);
182    }
183
184    @Override
185    final Object internalGetSetObjectProperty(SimplePropertyDescriptor propertyboolean getObject value) {
186        if (property == OPERATOR_PROPERTY) {
187            if (get) {
188                return getOperator();
189            } else {
190                setOperator((Operatorvalue);
191                return null;
192            }
193        }
194        // allow default implementation to flag the error
195        return super.internalGetSetObjectProperty(propertygetvalue);
196    }
197
198    @Override
199    final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor propertyboolean getASTNode child) {
200        if (property == OPERAND_PROPERTY) {
201            if (get) {
202                return getOperand();
203            } else {
204                setOperand((Expressionchild);
205                return null;
206            }
207        }
208        // allow default implementation to flag the error
209        return super.internalGetSetChildProperty(propertygetchild);
210    }
211
212    @Override
213    final int getNodeType0() {
214        return POSTFIX_EXPRESSION;
215    }
216
217    @Override
218    ASTNode clone0(AST target) {
219        PostfixExpression result = new PostfixExpression(target);
220        result.setSourceRange(getStartPosition(), getLength());
221        result.setOperator(getOperator());
222        result.setOperand((ExpressiongetOperand().clone(target));
223        return result;
224    }
225
226    @Override
227    final boolean subtreeMatch0(ASTMatcher matcherObject other) {
228        // dispatch to correct overloaded match method
229        return matcher.match(this, other);
230    }
231
232    @Override
233    void accept0(ASTVisitor visitor) {
234        boolean visitChildren = visitor.visit(this);
235        if (visitChildren) {
236            acceptChild(visitorgetOperand());
237        }
238        visitor.endVisit(this);
239    }
240
241    /**
242     * Returns the operator of this postfix expression.
243     *
244     * @return the operator
245     */
246    public PostfixExpression.Operator getOperator() {
247        return this.operator;
248    }
249
250    /**
251     * Sets the operator of this postfix expression.
252     *
253     * @param operator the operator
254     * @exception IllegalArgumentException if the argument is incorrect
255     */
256    public void setOperator(PostfixExpression.Operator operator) {
257        if (operator == null) {
258            throw new IllegalArgumentException();
259        }
260        preValueChange(OPERATOR_PROPERTY);
261        this.operator = operator;
262        postValueChange(OPERATOR_PROPERTY);
263    }
264
265    /**
266     * Returns the operand of this postfix expression.
267     *
268     * @return the operand expression node
269     */
270    public Expression getOperand() {
271        if (this.operand  == null) {
272            // lazy init must be thread-safe for readers
273            synchronized (this) {
274                if (this.operand == null) {
275                    preLazyInit();
276                    this.operand= new SimpleName(this.ast);
277                    postLazyInit(this.operandOPERAND_PROPERTY);
278                }
279            }
280        }
281        return this.operand;
282    }
283
284    /**
285     * Sets the operand of this postfix expression.
286     *
287     * @param expression the operand expression node
288     * @exception IllegalArgumentException if:
289     * <ul>
290     * <li>the node belongs to a different AST</li>
291     * <li>the node already has a parent</li>
292     * <li>a cycle in would be created</li>
293     * </ul>
294     */
295    public void setOperand(Expression expression) {
296        if (expression == null) {
297            throw new IllegalArgumentException();
298        }
299        ASTNode oldChild = this.operand;
300        preReplaceChild(oldChildexpressionOPERAND_PROPERTY);
301        this.operand = expression;
302        postReplaceChild(oldChildexpressionOPERAND_PROPERTY);
303    }
304
305    @Override
306    int memSize() {
307        // treat Operator as free
308        return BASE_NODE_SIZE + 2 * 4;
309    }
310
311    @Override
312    int treeSize() {
313        return
314            memSize()
315            + (this.operand == null ? 0 : getOperand().treeSize());
316    }
317}
318
MembersX
PostfixExpression:OPERATOR_PROPERTY
PostfixExpression:Operator:Operator
PostfixExpression:accept0
PostfixExpression:getNodeType0
PostfixExpression:PROPERTY_DESCRIPTORS
PostfixExpression:internalGetSetChildProperty
PostfixExpression:clone0
PostfixExpression:Operator:token
PostfixExpression:operand
PostfixExpression:internalGetSetObjectProperty
PostfixExpression:setOperator
PostfixExpression:treeSize
PostfixExpression:internalStructuralPropertiesForType
PostfixExpression:clone0:Block:result
PostfixExpression:setOperand
PostfixExpression:Operator:toString
PostfixExpression:Operator:CODES
PostfixExpression:Operator:toOperator
PostfixExpression:PostfixExpression
PostfixExpression:getOperator
PostfixExpression:Operator:Block:ops
PostfixExpression:Block:propertyList
PostfixExpression:subtreeMatch0
PostfixExpression:Operator:DECREMENT
PostfixExpression:memSize
PostfixExpression:accept0:Block:visitChildren
PostfixExpression:Operator:INCREMENT
PostfixExpression:propertyDescriptors
PostfixExpression:getOperand
PostfixExpression:OPERAND_PROPERTY
PostfixExpression:operator
PostfixExpression:setOperand:Block:oldChild
Members
X