EclipseJDT Source Viewer

Home|eclipse_jdt/src/org/eclipse/jdt/core/dom/SwitchCase.java
1/*******************************************************************************
2 * Copyright (c) 2000, 2021 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 * Contributors:
11 *     IBM Corporation - initial API and implementation
12 *******************************************************************************/
13
14package org.eclipse.jdt.core.dom;
15
16import java.util.ArrayList;
17import java.util.List;
18
19/**
20 * Switch case AST node type. A switch case is a special kind of node used only
21 * in switch statements. It is a <code>Statement</code> in name only.
22 * <pre>
23 * SwitchCase:
24 *         <b>case</b> Expression  <b>:</b>
25 *         <b>default</b> <b>:</b>
26 *
27 * Switch case allows multiple expressions and '->' as part of Java 12 preview feature (JEP 325)
28 *        <b>case</b> [ Expression { <b>,</b> Expression } ]  <b>{ : | ->}</b>
29 *        <b>default</b> <b>{ : | ->}</b>
30 * </pre>
31 *
32 * @since 2.0
33 * @noinstantiate This class is not intended to be instantiated by clients.
34 */
35@SuppressWarnings("rawtypes")
36public class SwitchCase extends Statement {
37
38    /**
39     * The "expression" structural property of this node type (child type: {@link Expression}).
40     * @since 3.0
41     * @deprecated In the JLS 12 15.28.1 API, this property is replaced by {@link #EXPRESSIONS2_PROPERTY }.
42     */
43    public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
44        new ChildPropertyDescriptor(SwitchCase.class"expression"Expression.classOPTIONALCYCLE_RISK); //$NON-NLS-1$
45
46    /**
47     * The "expression" structural property of this node type (child type: {@link Expression}). (added in JEP 325).
48     * @since 3.18
49     */
50    public static final ChildListPropertyDescriptor EXPRESSIONS2_PROPERTY  =
51            new ChildListPropertyDescriptor(SwitchCase.class"expression"Expression.classCYCLE_RISK); //$NON-NLS-1$);
52
53    /**
54     * The "switchLabeledRule" structural property of this node type (type: {@link Boolean}).
55     * @since 3.18
56     */
57    public static final SimplePropertyDescriptor SWITCH_LABELED_RULE_PROPERTY =
58        new SimplePropertyDescriptor(SwitchCase.class"switchLabeledRule"boolean.classMANDATORY); //$NON-NLS-1$
59
60    /**
61     * A list of property descriptors (element type:
62     * {@link StructuralPropertyDescriptor}),
63     * or null if uninitialized.
64     */
65    private static final List PROPERTY_DESCRIPTORS;
66
67    /**
68     * A list of property descriptors (element type:
69     * {@link StructuralPropertyDescriptor}),
70     * or null if uninitialized.
71     */
72    private static final List PROPERTY_DESCRIPTORS_13;
73
74    static {
75        List propertyList = new ArrayList(2);
76        createPropertyList(SwitchCase.classpropertyList);
77        addProperty(EXPRESSION_PROPERTYpropertyList);
78        PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
79
80        propertyList = new ArrayList(2);
81        createPropertyList(SwitchCase.classpropertyList);
82        addProperty(EXPRESSIONS2_PROPERTY , propertyList);
83        addProperty(SWITCH_LABELED_RULE_PROPERTYpropertyList);
84        PROPERTY_DESCRIPTORS_13 = reapPropertyList(propertyList);
85    }
86
87    /**
88     * Returns a list of structural property descriptors for this node type.
89     * Clients must not modify the result.
90     *
91     * @param apiLevel the API level; one of the
92     * <code>AST.JLS*</code> constants
93     * @return a list of property descriptors (element type:
94     * {@link StructuralPropertyDescriptor})
95     * @since 3.0
96     */
97    public static List propertyDescriptors(int apiLevel) {
98        if (apiLevel >= AST.JLS14_INTERNAL) {
99            return PROPERTY_DESCRIPTORS_13;
100        }
101        return PROPERTY_DESCRIPTORS;
102    }
103
104    /**
105     * The expression; <code>null</code> for none; lazily initialized (but
106     * does <b>not</b> default to none).
107     * @see #expressionInitialized
108     */
109    private Expression optionalExpression = null;
110
111    /**
112     * <code>true</code> indicates "->" and <code>false</code> indicates ":".
113     */
114    private boolean switchLabeledRule = false;
115
116
117    /**
118     * The expression list; <code>empty</code> for none;
119     */
120    private ASTNode.NodeList expressions = null;
121
122    /**
123     * Indicates whether <code>optionalExpression</code> has been initialized.
124     */
125    private boolean expressionInitialized = false;
126
127    /**
128     * Creates a new AST node for a switch case pseudo-statement owned by the
129     * given AST. By default, there is no expression, but legal, and switchLabeledRule
130     * is false which indicates ":".
131     *
132     * @param ast the AST that is to own this node
133     */
134    SwitchCase(AST ast) {
135        super(ast);
136        if (ast.apiLevel >= AST.JLS14_INTERNAL) {
137            this.expressions = new ASTNode.NodeList(EXPRESSIONS2_PROPERTY );
138        }
139    }
140
141    @Override
142    final List internalStructuralPropertiesForType(int apiLevel) {
143        return propertyDescriptors(apiLevel);
144    }
145
146    @Override
147    final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor propertyboolean getboolean value) {
148        if (property == SWITCH_LABELED_RULE_PROPERTY) {
149            if (get) {
150                return isSwitchLabeledRule();
151            } else {
152                setSwitchLabeledRule(value);
153                return false;
154            }
155        }
156        // allow default implementation to flag the error
157        return super.internalGetSetBooleanProperty(propertygetvalue);
158    }
159
160    @Override
161    final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor propertyboolean getASTNode child) {
162        if (property == EXPRESSION_PROPERTY) {
163            if (get) {
164                return getExpression();
165            } else {
166                setExpression((Expressionchild);
167                return null;
168            }
169        }
170        // allow default implementation to flag the error
171        return super.internalGetSetChildProperty(propertygetchild);
172    }
173
174    @Override
175    final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
176        if (property == EXPRESSIONS2_PROPERTY ) {
177            return expressions();
178        }
179        // allow default implementation to flag the error
180        return super.internalGetChildListProperty(property);
181    }
182
183    @Override
184    final int getNodeType0() {
185        return SWITCH_CASE;
186    }
187
188    @SuppressWarnings("unchecked")
189    @Override
190    ASTNode clone0(AST target) {
191        SwitchCase result = new SwitchCase(target);
192        result.setSourceRange(getStartPosition(), getLength());
193        result.copyLeadingComment(this);
194        if (this.ast.apiLevel >= AST.JLS14_INTERNAL) {
195            result.expressions().addAll(
196                ASTNode.copySubtrees(targetexpressions()));
197        } else {
198            result.setExpression(
199                    (ExpressionASTNode.copySubtree(targetgetExpression()));
200        }
201        return result;
202    }
203
204    @Override
205    final boolean subtreeMatch0(ASTMatcher matcherObject other) {
206        // dispatch to correct overloaded match method
207        return matcher.match(this, other);
208    }
209
210    @Override
211    void accept0(ASTVisitor visitor) {
212        boolean visitChildren = visitor.visit(this);
213        if (visitChildren) {
214            if (this.ast.apiLevel >= AST.JLS14_INTERNAL) {
215                acceptChildren(visitor, this.expressions);
216            } else {
217                acceptChild(visitorgetExpression());
218            }
219        }
220        visitor.endVisit(this);
221    }
222
223    /**
224     * Returns the expression of this switch case, or
225     * <code>null</code> if there is none (the "default:" case).
226     *
227     * @return the expression node, or <code>null</code> if there is none
228     * @deprecated use expressions() (see JLS 12)
229     */
230    public Expression getExpression() {
231        if (!this.expressionInitialized) {
232            // lazy init must be thread-safe for readers
233            synchronized (this) {
234                if (!this.expressionInitialized) {
235                    preLazyInit();
236                    this.optionalExpression = new SimpleName(this.ast);
237                    this.expressionInitialized = true;
238                    postLazyInit(this.optionalExpressionEXPRESSION_PROPERTY);
239                }
240            }
241        }
242        return this.optionalExpression;
243    }
244
245    /**
246     * Returns the list of expressions of this switch case, or
247     * <code>empty</code> if there is none (the "default:" case).
248     *
249     *  @return the list of expression nodes
250     *    (element type: {@link Expression})
251     * @exception UnsupportedOperationException if this operation is used below JLS14
252     * @since 3.22
253     */
254    public List expressions() {
255        if (this.expressions == null) {
256            unsupportedBelow14();
257        }
258        return this.expressions;
259    }
260
261    /**
262     * Sets the expression of this switch case, or clears it (turns it into
263     * the  "default:" case).
264     *
265     * @param expression the expression node, or <code>null</code> to
266     *    turn it into the  "default:" case
267     * @exception IllegalArgumentException if:
268     * <ul>
269     * <li>the node belongs to a different AST</li>
270     * <li>the node already has a parent</li>
271     * <li>a cycle in would be created</li>
272     * </ul>
273     * @deprecated see JLS 12
274     */
275    public void setExpression(Expression expression) {
276        ASTNode oldChild = this.optionalExpression;
277        preReplaceChild(oldChildexpressionEXPRESSION_PROPERTY);
278        this.optionalExpression = expression;
279        this.expressionInitialized = true;
280        postReplaceChild(oldChildexpressionEXPRESSION_PROPERTY);
281    }
282
283    /**
284     * Sets the switchLabeledRule of this switch case as <code>true</code> or <code>false</code>.
285     * <code>true</code> indicates "->" and <code>false</code> indicates ":".
286
287     * @param switchLabeledRule <code>true</code> or <code>false</code>
288     * @exception UnsupportedOperationException if this operation is used below JLS14
289     * @since 3.22
290     */
291    public void setSwitchLabeledRule(boolean switchLabeledRule) {
292        unsupportedBelow14();
293        preValueChange(SWITCH_LABELED_RULE_PROPERTY);
294        this.switchLabeledRule = switchLabeledRule;
295        postValueChange(SWITCH_LABELED_RULE_PROPERTY);
296    }
297
298    /**
299     * Gets the switchLabeledRule of this switch case as <code>true</code> or <code>false</code>.
300     *<code>true</code> indicates "->" and <code>false</code> indicates ":".
301     *
302     * @return switchLabeledRule <code>true</code> or <code>false</code>
303     * @exception UnsupportedOperationException if this operation is used below JLS14
304     * @since 3.22
305     */
306    public boolean isSwitchLabeledRule() {
307        unsupportedBelow14();
308        return this.switchLabeledRule;
309    }
310
311    /**
312     * Returns whether this switch case represents the "default:" case.
313     * <p>
314     * This convenience method is equivalent to
315     * <code>getExpression() == null</code> or <code>expressions().isEmpty()</code>.
316     * </p>
317     *
318     * @return <code>true</code> if this is the default switch case, and
319     *    <code>false</code> if this is a non-default switch case
320     */
321    public boolean isDefault()  {
322        if (this.ast.apiLevel >= AST.JLS14_INTERNAL) {
323            return expressions().isEmpty();
324        }
325        return getExpression() == null;
326    }
327
328    @Override
329    int memSize() {
330        return super.memSize() + 2 * 4;
331    }
332
333    @Override
334    int treeSize() {
335        return
336            memSize()
337            + (this.optionalExpression == null ? 0 : this.optionalExpression.treeSize());
338    }
339
340
341}
342
MembersX
SwitchCase:isSwitchLabeledRule
SwitchCase:internalGetChildListProperty
SwitchCase:PROPERTY_DESCRIPTORS
SwitchCase:accept0
SwitchCase:setExpression:Block:oldChild
SwitchCase:setSwitchLabeledRule
SwitchCase:clone0
SwitchCase:setExpression
SwitchCase:memSize
SwitchCase:expressionInitialized
SwitchCase:expressions
SwitchCase:getNodeType0
SwitchCase:SWITCH_LABELED_RULE_PROPERTY
SwitchCase:internalGetSetBooleanProperty
SwitchCase:switchLabeledRule
SwitchCase:propertyDescriptors
SwitchCase:accept0:Block:visitChildren
SwitchCase:SwitchCase
SwitchCase:clone0:Block:result
SwitchCase:PROPERTY_DESCRIPTORS_13
SwitchCase:subtreeMatch0
SwitchCase:EXPRESSIONS2_PROPERTY
SwitchCase:internalGetSetChildProperty
SwitchCase:optionalExpression
SwitchCase:Block:propertyList
SwitchCase:internalStructuralPropertiesForType
SwitchCase:EXPRESSION_PROPERTY
SwitchCase:treeSize
SwitchCase:isDefault
SwitchCase:getExpression
Members
X