EclipseJDT Source Viewer

Home|eclipse_jdt/src/org/eclipse/jdt/core/dom/TryStatement.java
1/*******************************************************************************
2 * Copyright (c) 2000, 2017 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.List;
19
20/**
21 * Try statement AST node type.
22 * <pre>
23 * TryStatement:
24 *     <b>try</b> [ <b>(</b> Resources <b>)</b> ]
25 *         Block
26 *         [ { CatchClause } ]
27 *         [ <b>finally</b> Block ]
28 * </pre>
29 *
30 * <p>
31 * Not all node arrangements will represent legal Java constructs. In particular,
32 * at least one resource, catch clause, or finally block must be present.</p>
33 *
34 * <p>A resource is either a {@link VariableDeclarationExpression} or (since JLS9) a {@link Name}.</p>
35 *
36 * @since 2.0
37 * @noinstantiate This class is not intended to be instantiated by clients.
38 * @noextend This class is not intended to be subclassed by clients.
39 */
40@SuppressWarnings({"rawtypes""unchecked"})
41public class TryStatement extends Statement {
42
43
44    /**
45     * The "resources" structural property of this node type (element type: {@link VariableDeclarationExpression}) (added in JLS4 API).
46     * @deprecated In the JLS9 API, this property is replaced by {@link #RESOURCES2_PROPERTY}.
47     * @since 3.7.1
48     */
49    public static final ChildListPropertyDescriptor RESOURCES_PROPERTY =
50        new ChildListPropertyDescriptor(TryStatement.class"resources"VariableDeclarationExpression.classCYCLE_RISK); //$NON-NLS-1$
51
52    /**
53     * The "resources" structural property of this node type (element type: {@link Expression}) (added in JLS9 API).
54     * @since 3.14
55     */
56    public static final ChildListPropertyDescriptor RESOURCES2_PROPERTY =
57        new ChildListPropertyDescriptor(TryStatement.class"resources"Expression.classCYCLE_RISK); //$NON-NLS-1$
58
59    /**
60     * The "body" structural property of this node type (child type: {@link Block}).
61     * @since 3.0
62     */
63    public static final ChildPropertyDescriptor BODY_PROPERTY =
64        new ChildPropertyDescriptor(TryStatement.class"body"Block.classMANDATORYCYCLE_RISK); //$NON-NLS-1$
65
66    /**
67     * The "catchClauses" structural property of this node type (element type: {@link CatchClause}).
68     * @since 3.0
69     */
70    public static final ChildListPropertyDescriptor CATCH_CLAUSES_PROPERTY =
71        new ChildListPropertyDescriptor(TryStatement.class"catchClauses"CatchClause.classCYCLE_RISK); //$NON-NLS-1$
72
73    /**
74     * The "finally" structural property of this node type (child type: {@link Block}).
75     * @since 3.0
76     */
77    public static final ChildPropertyDescriptor FINALLY_PROPERTY =
78        new ChildPropertyDescriptor(TryStatement.class"finally"Block.classOPTIONALCYCLE_RISK); //$NON-NLS-1$
79
80    /**
81     * A list of property descriptors (element type:
82     * {@link StructuralPropertyDescriptor}),
83     * or null if uninitialized.
84     */
85    private static final List PROPERTY_DESCRIPTORS;
86
87    /**
88     * A list of property descriptors (element type:
89     * {@link StructuralPropertyDescriptor}),
90     * or null if uninitialized.
91     * @since 3.7
92     */
93    private static final List PROPERTY_DESCRIPTORS_4_0;
94
95    /**
96     * A list of property descriptors (element type:
97     * {@link StructuralPropertyDescriptor}),
98     * or null if uninitialized.
99     * @since 3.14
100     */
101    private static final List PROPERTY_DESCRIPTORS_9_0;
102
103    static {
104        List propertyList = new ArrayList(4);
105        createPropertyList(TryStatement.classpropertyList);
106        addProperty(BODY_PROPERTYpropertyList);
107        addProperty(CATCH_CLAUSES_PROPERTYpropertyList);
108        addProperty(FINALLY_PROPERTYpropertyList);
109        PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
110
111        propertyList = new ArrayList(5);
112        createPropertyList(TryStatement.classpropertyList);
113        addProperty(RESOURCES_PROPERTYpropertyList);
114        addProperty(BODY_PROPERTYpropertyList);
115        addProperty(CATCH_CLAUSES_PROPERTYpropertyList);
116        addProperty(FINALLY_PROPERTYpropertyList);
117        PROPERTY_DESCRIPTORS_4_0 = reapPropertyList(propertyList);
118
119        propertyList = new ArrayList(5);
120        createPropertyList(TryStatement.classpropertyList);
121        addProperty(RESOURCES2_PROPERTYpropertyList);
122        addProperty(BODY_PROPERTYpropertyList);
123        addProperty(CATCH_CLAUSES_PROPERTYpropertyList);
124        addProperty(FINALLY_PROPERTYpropertyList);
125        PROPERTY_DESCRIPTORS_9_0 = reapPropertyList(propertyList);
126    }
127
128    /**
129     * Returns a list of structural property descriptors for this node type.
130     * Clients must not modify the result.
131     *
132     * @param apiLevel the API level; one of the
133     * <code>AST.JLS*</code> constants
134     * @return a list of property descriptors (element type:
135     * {@link StructuralPropertyDescriptor})
136     * @since 3.0
137     */
138    public static List propertyDescriptors(int apiLevel) {
139        switch (apiLevel) {
140            case AST.JLS2_INTERNAL :
141            case AST.JLS3_INTERNAL :
142                return PROPERTY_DESCRIPTORS;
143            case AST.JLS4_INTERNAL :
144            case AST.JLS8_INTERNAL :
145                return PROPERTY_DESCRIPTORS_4_0;
146            default :
147                return PROPERTY_DESCRIPTORS_9_0;
148        }
149    }
150
151    /**
152     * The resource expressions (element type: {@link Expression}).
153     * Null in JLS2 and JLS3. Added in JLS4.
154     * In the deprecated JLS4 and JLS8 APIs, this used to be
155     * (element type: {@link VariableDeclarationExpression}).
156     * Defaults to an empty list (see constructor).
157     * @since 3.7
158     */
159    private ASTNode.NodeList resources = null;
160
161    /**
162     * The body; lazily initialized; defaults to an empty block.
163     */
164    private Block body = null;
165
166    /**
167     * The catch clauses (element type: {@link CatchClause}).
168     * Defaults to an empty list.
169     */
170    private ASTNode.NodeList catchClauses =
171        new ASTNode.NodeList(CATCH_CLAUSES_PROPERTY);
172
173    /**
174     * The finally block, or <code>null</code> if none.
175     * Defaults to none.
176     */
177    private Block optionalFinallyBody = null;
178
179
180    /**
181     * Creates a new AST node for a try statement owned by the given
182     * AST. By default, the try statement has no resources, an empty block, no catch
183     * clauses, and no finally block.
184     * <p>
185     * N.B. This constructor is package-private.
186     * </p>
187     *
188     * @param ast the AST that is to own this node
189     */
190    TryStatement(AST ast) {
191        super(ast);
192        if (ast.apiLevel >= AST.JLS9_INTERNAL) {
193            this.resources = new ASTNode.NodeList(RESOURCES2_PROPERTY);
194        } else if (ast.apiLevel >= AST.JLS4_INTERNAL) {
195            this.resources = new ASTNode.NodeList(RESOURCES_PROPERTY);
196        }
197    }
198
199    @Override
200    final List internalStructuralPropertiesForType(int apiLevel) {
201        return propertyDescriptors(apiLevel);
202    }
203
204    @Override
205    final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor propertyboolean getASTNode child) {
206        if (property == BODY_PROPERTY) {
207            if (get) {
208                return getBody();
209            } else {
210                setBody((Blockchild);
211                return null;
212            }
213        }
214        if (property == FINALLY_PROPERTY) {
215            if (get) {
216                return getFinally();
217            } else {
218                setFinally((Blockchild);
219                return null;
220            }
221        }
222        // allow default implementation to flag the error
223        return super.internalGetSetChildProperty(propertygetchild);
224    }
225
226    @Override
227    final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
228        if (property == RESOURCES_PROPERTY || property == RESOURCES2_PROPERTY) {
229            return resources();
230        }
231        if (property == CATCH_CLAUSES_PROPERTY) {
232            return catchClauses();
233        }
234        // allow default implementation to flag the error
235        return super.internalGetChildListProperty(property);
236    }
237
238    @Override
239    final int getNodeType0() {
240        return TRY_STATEMENT;
241    }
242
243    @Override
244    ASTNode clone0(AST target) {
245        TryStatement result = new TryStatement(target);
246        result.setSourceRange(getStartPosition(), getLength());
247        result.copyLeadingComment(this);
248        if (this.ast.apiLevel >= AST.JLS4_INTERNAL) {
249            result.resources().addAll(
250                    ASTNode.copySubtrees(targetresources()));
251        }
252        result.setBody((BlockgetBody().clone(target));
253        result.catchClauses().addAll(
254            ASTNode.copySubtrees(targetcatchClauses()));
255        result.setFinally(
256            (BlockASTNode.copySubtree(targetgetFinally()));
257        return result;
258    }
259
260    @Override
261    final boolean subtreeMatch0(ASTMatcher matcherObject other) {
262        // dispatch to correct overloaded match method
263        return matcher.match(this, other);
264    }
265
266    @Override
267    void accept0(ASTVisitor visitor) {
268        boolean visitChildren = visitor.visit(this);
269        if (visitChildren) {
270            // visit children in normal left to right reading order
271            if (this.ast.apiLevel >= AST.JLS4_INTERNAL) {
272                acceptChildren(visitor, this.resources);
273            }
274            acceptChild(visitorgetBody());
275            acceptChildren(visitor, this.catchClauses);
276            acceptChild(visitorgetFinally());
277        }
278        visitor.endVisit(this);
279    }
280
281    /**
282     * Returns the body of this try statement.
283     *
284     * @return the try body
285     */
286    public Block getBody() {
287        if (this.body == null) {
288            // lazy init must be thread-safe for readers
289            synchronized (this) {
290                if (this.body == null) {
291                    preLazyInit();
292                    this.body = new Block(this.ast);
293                    postLazyInit(this.bodyBODY_PROPERTY);
294                }
295            }
296        }
297        return this.body;
298    }
299
300    /**
301     * Sets the body of this try statement.
302     *
303     * @param body the block node
304     * @exception IllegalArgumentException if:
305     * <ul>
306     * <li>the node belongs to a different AST</li>
307     * <li>the node already has a parent</li>
308     * <li>a cycle in would be created</li>
309     * </ul>
310     */
311    public void setBody(Block body) {
312        if (body == null) {
313            throw new IllegalArgumentException();
314        }
315        ASTNode oldChild = this.body;
316        preReplaceChild(oldChildbodyBODY_PROPERTY);
317        this.body = body;
318        postReplaceChild(oldChildbodyBODY_PROPERTY);
319    }
320
321    /**
322     * Returns the live ordered list of catch clauses for this try statement.
323     *
324     * @return the live list of catch clauses
325     *    (element type: {@link CatchClause})
326     */
327    public List catchClauses() {
328        return this.catchClauses;
329    }
330
331    /**
332     * Returns the finally block of this try statement, or <code>null</code> if
333     * this try statement has <b>no</b> finally block.
334     *
335     * @return the finally block, or <code>null</code> if this try statement
336     *    has none
337     */
338    public Block getFinally() {
339        return this.optionalFinallyBody;
340    }
341
342    /**
343     * Sets or clears the finally block of this try statement.
344     *
345     * @param block the finally block node, or <code>null</code> if
346     *    there is none
347     * @exception IllegalArgumentException if:
348     * <ul>
349     * <li>the node belongs to a different AST</li>
350     * <li>the node already has a parent</li>
351     * <li>a cycle in would be created</li>
352     * </ul>
353     */
354    public void setFinally(Block block) {
355        ASTNode oldChild = this.optionalFinallyBody;
356        preReplaceChild(oldChildblockFINALLY_PROPERTY);
357        this.optionalFinallyBody = block;
358        postReplaceChild(oldChildblockFINALLY_PROPERTY);
359    }
360
361    /**
362     * Returns the live ordered list of resources for this try statement (added in JLS4 API).
363     *
364     * <p>A resource is either a {@link VariableDeclarationExpression} or (since JLS9) a {@link Name}.</p>
365     *
366     * @return the live list of resources (element type: {@link Expression}).
367     *    In the deprecated JLS4 and JLS8 APIs, this used to be
368     *    (element type: {@link VariableDeclarationExpression}).
369     * @exception UnsupportedOperationException if this operation is used
370     *            in a JLS2 or JLS3 AST
371     * @since 3.7.1
372     */
373    public List resources() {
374        // more efficient than just calling unsupportedIn2_3() to check
375        if (this.resources == null) {
376            unsupportedIn2_3();
377        }
378        return this.resources;
379    }
380
381    @Override
382    int memSize() {
383        return super.memSize() + 4 * 4;
384    }
385
386    @Override
387    int treeSize() {
388        return
389            memSize()
390            + (this.resources == null ? 0 : this.resources.listSize())
391            + (this.body == null ? 0 : getBody().treeSize())
392            + this.catchClauses.listSize()
393            + (this.optionalFinallyBody == null ? 0 : getFinally().treeSize());
394    }
395}
396
MembersX
TryStatement:PROPERTY_DESCRIPTORS_9_0
TryStatement:PROPERTY_DESCRIPTORS_4_0
TryStatement:Block:propertyList
TryStatement:setBody:Block:oldChild
TryStatement:getFinally
TryStatement:treeSize
TryStatement:propertyDescriptors
TryStatement:clone0:Block:result
TryStatement:setFinally
TryStatement:RESOURCES_PROPERTY
TryStatement:setBody
TryStatement:setFinally:Block:oldChild
TryStatement:getNodeType0
TryStatement:internalGetSetChildProperty
TryStatement:accept0
TryStatement:internalStructuralPropertiesForType
TryStatement:BODY_PROPERTY
TryStatement:CATCH_CLAUSES_PROPERTY
TryStatement:body
TryStatement:internalGetChildListProperty
TryStatement:memSize
TryStatement:subtreeMatch0
TryStatement:FINALLY_PROPERTY
TryStatement:PROPERTY_DESCRIPTORS
TryStatement:accept0:Block:visitChildren
TryStatement:catchClauses
TryStatement:resources
TryStatement:RESOURCES2_PROPERTY
TryStatement:clone0
TryStatement:TryStatement
TryStatement:optionalFinallyBody
TryStatement:getBody
Members
X